rmdir: failed to remove 'dir': Directory not empty

Linux Directory Not Empty Error: rmdir Fix That Works

You tried rmdir and it refused because the directory has hidden or nested files. Here's the fastest fix, from a one-liner to the nuclear option.

You typed rmdir somedir and got back rmdir: failed to remove 'somedir': Directory not empty. Annoying, but this one is honest — rmdir only removes empty directories. If it says the directory isn't empty, it isn't. Your job is to figure out what's still inside and get rid of it.

The culprit is almost always hidden files. A directory can look empty in ls but still have .git, .DS_Store, .env, or a nested folder you forgot about. Docker volume mounts and npm installs leave junk behind all the time.

30-second fix: see what's actually in there

Before nuking anything, look. Run:

ls -la somedir

The -a is the part people forget. Plain ls hides dotfiles. ls -la shows everything, including . and .. which you can ignore.

If you see files listed, that's your answer. Delete them, then rmdir works:

rm somedir/* somedir/.* 2>/dev/null
rmdir somedir

Careful with that glob. somedir/.* will try to match . and .. which is a disaster if you're not careful. The 2>/dev/null swallows the resulting errors, but I don't love it as a habit.

Better idea: use find instead.

5-minute fix: find and delete cleanly

If the directory has nested subdirectories, the glob approach falls apart. Use find:

find somedir -mindepth 1 -delete
rmdir somedir

-mindepth 1 prevents find from trying to delete somedir itself before it's empty. Without that flag, find sometimes chokes on the order of operations.

Want to see what find would delete before you pull the trigger? Drop the -delete and just list:

find somedir -mindepth 1 -print

Run that first. Always. You don't want to find out the hard way that somedir was actually a symlink to /var/log.

15-minute fix: when rmdir still refuses

If rmdir keeps failing after you've cleared everything visible, something is holding the directory. Three usual suspects:

  1. Immutable attribute set. Check with lsattr -d somedir. If you see an i in the output, it's immutable. Clear it with chattr -i somedir. This happens on some hardened servers and anything touched by Ansible hardening roles.
  2. A process has the directory as its cwd. Run lsof +D somedir or fuser -v somedir. If something's using it, kill the process, close the shell, or stop the service.
  3. Mount point. Run mountpoint somedir. If it says yes, rmdir will never work — you need umount somedir first. This bites people who unmount Docker volumes and try to delete the mount source without unmounting.

Check attributes first. It's the fastest of the three:

lsattr -d somedir
lsof +D somedir
mountpoint somedir

The nuclear option: rm -rf

Yes, rm -rf somedir works. No, it's not always the right answer. Here's the trade-off: it deletes everything without asking, ignores permissions (mostly), and doesn't care about hidden files. That's great when you're sure. It's catastrophic when you're not.

Before you type it, do two things:

  1. Run pwd and confirm you're where you think you are. An extra space between rm -rf and the path has ended careers.
  2. Check for symlinks with ls -la. A symlink pointing at / plus rm -rf symlink/ is a very bad day. GNU coreutils won't follow the symlink itself, but the trailing slash changes things on some systems.

If you're sure, go:

rm -rf somedir

There's no undo. That's the deal.

Why rmdir even exists

Fair question. rmdir is a safety net. On production boxes where a stray rm -rf takes out the wrong folder, rmdir forces you to be deliberate. It won't delete anything you haven't explicitly emptied. Some shops require it in scripts precisely for that reason.

If you're scripting cleanup, prefer find somedir -mindepth 1 -delete && rmdir somedir over rm -rf. It fails loudly when something unexpected shows up, instead of silently eating it.

Common traps

  • Trailing slash on symlinks. rm -rf link/ can behave differently than rm -rf link. Skip the slash.
  • Wildcards expanding to nothing. rm somedir/* when the dir has only dotfiles does nothing, and then rmdir still fails. Use find.
  • NFS and stale handles. On NFS, deleted files can linger if a client holds them open. lsof +D on the server side usually reveals it.
  • Case sensitivity. Linux is case-sensitive. Somedir and somedir are different folders. Yes, people hit this.

When it's not actually a directory

Sometimes rmdir throws the not-empty error because the path is a file with a misleading name, or a broken mount. Run file somedir and stat somedir. If stat shows a device or inode weirdness, you're not dealing with a normal folder and none of the above applies.

Bottom line: ls -la first, find -delete second, rm -rf when you've earned it. The error is doing you a favor — pay attention to what it's telling you.

Related Errors in Linux & Unix
Fix 'command not found' in Linux: PATH and alternatives ESTALE NFS Stale File Handle: Quick Fix That Works cpufreq: governor not found or failed CPU Frequency Scaling Governor Not Working Fix 502 Bad Gateway Nginx 502 Bad Gateway: Quick Fix for PHP-FPM Issues

Was this solution helpful?

EP
Erropedia Team
Tech Support Editors
The Erropedia editorial team researches and documents real-world tech errors from across Windows, Linux, macOS, networking, databases, cloud platforms, and more. Every solution is reviewed for accuracy and updated as software and systems evolve.