Fixing "device is busy" on umount
What does "device is busy" actually mean?
Conclusion: Something still uses the filesystem you are trying to unmount - a process, a stacked mount, or swap. The kernel returns
EBUSYand refuses umount. The first step is to find what is holding it, not to force it.
A typical failure looks like this:
umount: /mnt/data: target is busy.
On older distributions or some tools, the same condition appears as device is busy or device or resource busy (the EBUSY errno). The wording differs, but the cause is identical: something still references the target.
Holders fall into a few groups. Triage them in this order:
- A. A process has a file open (most common) - an open file under the mount, a running binary, a log being written
- B. A current directory inside the mount - a shell or daemon whose cwd is under
/mnt/data - C. A nested mount - a bind mount or overlay stacked on top of it
- D. Used as swap / loop - the device backs swap or a loop device
device is busy and Read-only file system are different problems. The former means "in use, cannot detach"; the latter means "writes are blocked." Don't confuse the messages. For read-only, see Fixing "Read-only file system".
How do I find what is holding the mount?
Conclusion: Start with
fuser -vm <mountpoint>to list every process using that filesystem. TheACCESScolumn distinguishes an open file (f), current directory (c), running binary (e), and mmap (m). Uselsoffor per-file detail.
Sweep by mount with fuser
-m treats the argument as a mountpoint (or block device) and returns every process using that filesystem. -v adds detail.
fuser -vm /mnt/data
USER PID ACCESS COMMAND
/mnt/data: root kernel mount /mnt/data
alice 2314 ..c.. bash
alice 2890 F.... tail
Read the ACCESS column - it is the direct answer to "why is it busy?"
c… the process's current directory is under the mount (pattern B)e… a binary under the mount is executingf… a file is open (uppercaseFmeans open for writing)r… used as a root directorym… a file is mmap'd (shared libraries, etc.)
In the example above, bash (cwd inside) and tail (file open) are the holders.
Drill into individual files with lsof
To know exactly which file is held, use lsof. Use +D to recurse under a mountpoint, or +f -- to query by device.
# Files open under the mountpoint lsof +D /mnt/data # By block device (useful when the mountpoint path itself is broken) lsof +f -- /dev/sdb1
lsof +D stats the whole tree and is slow on large directories. In practice, run fuser -vm first to find the cause, then use lsof for detail.
How do I stop the holders and unmount?
Conclusion: Terminate the holders gracefully first (cd out / stop the service / SIGTERM), then umount. If they persist,
fuser -kforce-kills them - but SIGKILL risks data loss, so keep it as the last resort.
1. The safe order: leave or stop cleanly
- If it is just your own shell's cwd, step out:
cd /
- If a service holds it, stop the service (more reliable and safer than kill):
sudo systemctl stop myapp.service
- For individual processes, find the PID and start with a gentle signal:
kill 2890 # SIGTERM (lets it clean up)
2. Last resort: fuser -k to kill in bulk
Processes that won't exit cleanly can be killed together with fuser -k. But -k sends SIGKILL by default, which can corrupt data mid-write.
# Confirm first (-i prompts per process) sudo fuser -kim /mnt/data
/mnt/data: 2890c 2314c Kill process 2890 ? (y/N) y
-k… send a signal to the holders (default SIGKILL)-i… confirm each one (strongly recommended)-m… by mount
Running fuser -km / against the root or a live critical filesystem SIGKILLs every process on the system and takes the server down. Double-check the path and always use -i in production. SIGKILL exits processes without flushing write buffers, which can corrupt database or log data.
Once the holders are cleared, unmount again:
sudo umount /mnt/data
Should I use lazy or force umount?
Conclusion: To detach immediately from the tree, use
umount -l(lazy). For an unresponsive NFS mount, useumount -f(force). Both are workarounds that don't resolve the holder, so don't rely on them routinely.
Lazy umount (-l)
Detaches the filesystem from the tree right now and cleans up once references disappear. An emergency exit when you can't (or won't) kill the holders.
sudo umount -l /mnt/data
Caveats:
- The mountpoint disappears, but open FDs stay alive (processes keep holding the old files). Full release happens only after they exit.
- Re-mounting the same device immediately can conflict with lingering references.
- It does not guarantee that unwritten data is flushed. On critical filesystems, fix the cause first.
Force umount (-f)
Mainly for an unresponsive NFS mount - it forcibly detaches a hung mount whose server is down.
sudo umount -f /mnt/nfs
On local ext4/xfs, -f rarely helps (the busy cause is a local process). For NFS hangs, also read Fixing "Stale file handle" on NFS.
What if it's busy but no process shows up?
Conclusion: If
fuser/lsofshow nothing yet it's still busy, the cause is not an open file. Check four things in order: nested mounts, swap, loop devices, and NFS exports.
1. Check for nested mounts (bind / overlay)
If another mount is stacked on top, the parent stays busy. Inspect the tree with findmnt -R and unmount children first.
findmnt -R /mnt/data
TARGET SOURCE FSTYPE OPTIONS /mnt/data /dev/sdb1 ext4 rw,relatime └─/mnt/data/cache tmpfs tmpfs rw
Here, unmount the child /mnt/data/cache first. Common with Docker overlays and mount --bind.
2. Is it used as swap?
If the partition backs swap, you obviously can't unmount it. Check with swapon --show and run swapoff.
swapon --show sudo swapoff /dev/sdb2
3. Is a loop device holding it?
If you loop-mounted an image file, a reference via the loop device remains. Check with losetup -a and detach.
losetup -a sudo losetup -d /dev/loop0
4. Is it exported over NFS?
If the filesystem is exported by an NFS server, it stays busy. Release exports with exportfs.
sudo exportfs -ua # temporarily unexport everything
Fastest path: ① fuser -vm /mnt/data to see who holds it → ② terminate gracefully (cd / systemctl stop / kill) → ③ umount again → if it persists ④ check non-process causes with findmnt -R, swapon --show, losetup -a → ⑤ only in emergencies, umount -l. Never skip identifying the cause - that's the one rule that prevents accidents.