diff --git a/sys/vfs/hammer/hammer_object.c b/sys/vfs/hammer/hammer_object.c
index aca7a29..ee30f33 100644
--- a/sys/vfs/hammer/hammer_object.c
+++ b/sys/vfs/hammer/hammer_object.c
@@ -703,7 +703,8 @@ failed:
  * cursor must be seeked to the directory entry record being deleted.
  *
  * The related inode should be share-locked by the caller.  The caller is
- * on the frontend.
+ * on the frontend.  It could also be NULL indicating that the directory
+ * entry being removed has no related inode.
  *
  * This function can return EDEADLK requiring the caller to terminate
  * the cursor, any locks, wait on the returned record, and retry.
@@ -749,9 +750,18 @@ hammer_ip_del_directory(struct hammer_transaction *trans,
 		record->type = HAMMER_MEM_RECORD_DEL;
 		record->leaf.base = cursor->leaf->base;
 
+		/*
+		 * ip may be NULL, indicating the deletion of a directory
+		 * entry which has no related inode.
+		 */
 		record->target_ip = ip;
-		record->flush_state = HAMMER_FST_SETUP;
-		TAILQ_INSERT_TAIL(&ip->target_list, record, target_entry);
+		if (ip) {
+			record->flush_state = HAMMER_FST_SETUP;
+			TAILQ_INSERT_TAIL(&ip->target_list, record,
+					  target_entry);
+		} else {
+			record->flush_state = HAMMER_FST_IDLE;
+		}
 
 		/*
 		 * The inode now has a dependancy and must be taken out of
@@ -762,7 +772,7 @@ hammer_ip_del_directory(struct hammer_transaction *trans,
 		 * reflush when the dependancies are disposed of if someone
 		 * is waiting on the inode.
 		 */
-		if (ip->flush_state == HAMMER_FST_IDLE) {
+		if (ip && ip->flush_state == HAMMER_FST_IDLE) {
 			hammer_ref(&ip->lock);
 			ip->flush_state = HAMMER_FST_SETUP;
 			if (ip->flags & HAMMER_INODE_FLUSHW)
@@ -786,15 +796,18 @@ hammer_ip_del_directory(struct hammer_transaction *trans,
 	 * on-media until we unmount.
 	 */
 	if (error == 0) {
-		--ip->ino_data.nlinks;
+		if (ip)
+			--ip->ino_data.nlinks;	/* do before we might block */
 		dip->ino_data.mtime = trans->time;
 		hammer_modify_inode(dip, HAMMER_INODE_MTIME);
-		hammer_modify_inode(ip, HAMMER_INODE_DDIRTY);
-		if (ip->ino_data.nlinks == 0 &&
-		    (ip->vp == NULL || (ip->vp->v_flag & VINACTIVE))) {
-			hammer_done_cursor(cursor);
-			hammer_inode_unloadable_check(ip, 1);
-			hammer_flush_inode(ip, 0);
+		if (ip) {
+			hammer_modify_inode(ip, HAMMER_INODE_DDIRTY);
+			if (ip->ino_data.nlinks == 0 &&
+			    (ip->vp == NULL || (ip->vp->v_flag & VINACTIVE))) {
+				hammer_done_cursor(cursor);
+				hammer_inode_unloadable_check(ip, 1);
+				hammer_flush_inode(ip, 0);
+			}
 		}
 
 	}
diff --git a/sys/vfs/hammer/hammer_vnops.c b/sys/vfs/hammer/hammer_vnops.c
index c2abe5f..e39a69c 100644
--- a/sys/vfs/hammer/hammer_vnops.c
+++ b/sys/vfs/hammer/hammer_vnops.c
@@ -1298,6 +1298,10 @@ hammer_vop_readdir(struct vop_readdir_args *ap)
 
 	/*
 	 * Handle artificial entries
+	 *
+	 * It should be noted that the minimum value for a directory
+	 * hash key on-media is 0x0000000100000000, so we can use anything
+	 * less then that to represent our 'special' key space.
 	 */
 	error = 0;
 	if (saveoff == 0) {
@@ -2811,15 +2815,17 @@ retry:
 				      0, &error);
 		hammer_lock_sh(&cursor.ip->lock);
 		if (error == ENOENT) {
-			kprintf("obj_id %016llx\n", cursor.data->entry.obj_id);
-			Debugger("ENOENT unlinking object that should exist");
+			kprintf("HAMMER: Warning: Removing directory entry"
+				" whos inode does not exist: %016llx\n",
+				(long long)cursor.data->entry.obj_id);
+			error = 0;
 		}
 
 		/*
 		 * If isdir >= 0 we validate that the entry is or is not a
 		 * directory.  If isdir < 0 we don't care.
 		 */
-		if (error == 0 && isdir >= 0) {
+		if (error == 0 && isdir >= 0 && ip) {
 			if (isdir &&
 			    ip->ino_data.obj_type != HAMMER_OBJTYPE_DIRECTORY) {
 				error = ENOTDIR;
@@ -2841,8 +2847,8 @@ retry:
 		 * If any changes whatsoever have been made to the cursor
 		 * set EDEADLK and retry.
 		 */
-		if (error == 0 && ip->ino_data.obj_type ==
-				  HAMMER_OBJTYPE_DIRECTORY) {
+		if (error == 0 && ip && ip->ino_data.obj_type ==
+				        HAMMER_OBJTYPE_DIRECTORY) {
 			hammer_unlock_cursor(&cursor);
 			error = hammer_ip_check_directory_empty(trans, ip);
 			hammer_lock_cursor(&cursor);
@@ -2870,7 +2876,7 @@ retry:
 			cache_setunresolved(nch);
 			cache_setvp(nch, NULL);
 			/* XXX locking */
-			if (ip->vp) {
+			if (ip && ip->vp) {
 				hammer_knote(ip->vp, NOTE_DELETE);
 				cache_inval_vp(ip->vp, CINV_DESTROY);
 			}
