Three of the most common error messages on a Linux box are really the same question wearing different clothes:
bind: Address already in use— something already has that portumount: target is busy— something is still inside that mount pointdfsays the disk is full butducannot find the space — something is holding a file you already deleted
The question in all three cases is which process has this open, and lsof is the tool that answers it. The name is “list open files”, which undersells it, because on Linux nearly everything is a file — sockets, pipes, devices and directories all count.
Installing it
It is not always present on a minimal server image.
sudo apt install lsof psmisc # Debian, Ubuntu
sudo dnf install lsof psmisc # Fedora, RHEL, Rocky, Alma
sudo pacman -S lsof psmisc # Archpsmisc brings fuser, which does a narrower job in a shorter line. On Alpine, lsof is in the main repository but the busybox fuser is more limited.
Run it as root
Without sudo, lsof can only see your own processes, and it will not tell you that it is hiding things — it prints a partial answer that looks complete. This is the single most common reason someone concludes “nothing has the port open” when something clearly does.
What has this port?
sudo lsof -i :8080That lists every process with something on port 8080, in or out. To narrow it to the thing actually listening:
sudo lsof -i :8080 -sTCP:LISTEN
# everything listening anywhere, which is a useful audit
sudo lsof -i -P -n | grep LISTEN-P stops it translating port numbers into service names (so you see :8080 rather than :http-alt) and -n stops it doing reverse DNS on every address. Together they make the output both faster and easier to read, and you will want them almost every time.
The modern alternative for ports specifically is ss, which is quicker:
sudo ss -tulpn | grep :8080Use ss when the question is only about network sockets. Use lsof when the question might be about anything else, which is most of the time.
What is keeping this mount busy?
sudo lsof +D /mnt/backup # everything under the directory
sudo fuser -vm /mnt/backup # everything using that mount point+D walks the whole tree, which is thorough and slow on a large mount. fuser -vm asks a different question — what is using this filesystem — and answers it almost instantly, which usually makes it the better first attempt for a stuck umount.
The answer is frequently a shell someone left sitting in the directory, including your own. A process whose working directory is inside the mount counts as using it, even if it has no files open.
The disk that is full of nothing
Deleting a file does not free the space if something still has it open. Unlinking removes the name from the directory; the data survives until the last file descriptor pointing at it is closed. So a log file someone deleted to “free up space” while the service is still writing to it stays on disk, invisible to du, until that service is restarted. This is why df and du disagree, and it is almost always the answer when they do.
Find them:
sudo lsof +L1+L1 means “files with fewer than one link” — deleted, but still held. The SIZE/OFF column tells you how much space you get back, and restarting the process named in the COMMAND column is what actually releases it.
If a restart is genuinely not possible right now, you can truncate the file through its descriptor. The process keeps writing at its old offset, so the file will appear sparse afterwards, but the space comes back immediately:
# PID 1234, file descriptor 5, from the lsof output
sudo truncate -s 0 /proc/1234/fd/5Treat that as a way to survive until a maintenance window, not as the fix.
The other questions worth knowing
| Question | Command |
|---|---|
| What does this process have open? | sudo lsof -p 1234 |
| What has this exact file open? | sudo lsof /var/log/app.log |
| What is this user running, and with what open? | sudo lsof -u deploy |
| Everything a named program has open | sudo lsof -c nginx |
| Which process is talking to this host | sudo lsof -i @10.0.0.5 |
| Only IPv4, only IPv6 | lsof -i4 / lsof -i6 |
| Everything except this user | sudo lsof -u ^root |
By default multiple conditions are combined with OR, not AND, which surprises people. lsof -u deploy -i :443 shows everything deploy has open plus everything on 443. Add -a to mean AND:
sudo lsof -a -u deploy -i :443Reading the output
| Column | Means |
|---|---|
| COMMAND | The program name, truncated to nine characters by default (+c 0 shows it in full) |
| PID | Process ID — what you feed to systemctl status or kill |
| USER | Who it runs as |
| FD | Descriptor number, plus cwd, txt, mem, rtd; u is read/write, r read, w write |
| TYPE | REG file, DIR directory, IPv4/IPv6 socket, unix socket, FIFO pipe |
| NAME | The path, or the connection — and (deleted) when the file is gone but held |
An FD of cwd is the one to look for when a mount will not unmount: that process is not using a file, it is simply standing there.
fuser, for when you already know what you want to do
fuser is smaller and blunter. Where lsof describes, fuser can act.
fuser -v /var/log/app.log # who has this file, with names
fuser -vm /mnt/backup # who is using this filesystem
fuser -v -n tcp 8080 # who has this TCP port
sudo fuser -k -TERM /mnt/backup # ask them all to stopfuser -k kills processes. Without a signal argument it sends SIGKILL, which gives the process no chance to flush anything to disk. Always look first with -v, and if you do use it, prefer -TERM. Running fuser -k on a mount that turns out to contain a database directory is a bad afternoon.
Common problems
| Symptom | Cause | Fix |
|---|---|---|
| Empty output when something obviously has the port | Not running as root | Add sudo |
lsof: WARNING: can't stat() fuse.gvfsd-fuse | A user filesystem it cannot read | Harmless — add -w to silence warnings |
| Takes many seconds to return | Reverse DNS on every address | Add -n, and -P for ports |
Port free according to lsof, still cannot bind | Socket in TIME_WAIT, or a container publishing it | ss -tan | grep 8080; check docker ps |
umount still busy with nothing listed | An NFS server or a kernel thread holds it | umount -l to detach lazily, then investigate |
| Two filters returned far too much | Conditions default to OR | Add -a |
Quick reference
sudo lsof -i :8080 -sTCP:LISTEN # what is on this port
sudo lsof -i -P -n | grep LISTEN # everything listening
sudo lsof +L1 # deleted files still holding space
sudo lsof +D /mnt/backup # everything under a directory
sudo fuser -vm /mnt/backup # what is using a mount, fast
sudo lsof -p 1234 # what one process has open
sudo lsof -c nginx # what a named program has open
sudo lsof -a -u deploy -i :443 # AND, not OR
sudo truncate -s 0 /proc/1234/fd/5 # emergency space, not a fixRelated reading
- The Life of a File Descriptor — the long version of what
lsofis listing, and why a deleted file can still be eating your disk - Finding and freeing disk space — the wider version of the
dfversusduproblem - Processes: ps, top and kill — what to do once you have the PID
- ip and modern network inspection — including more on
ss - Disks and mounting — why the mount will not go away
- How filesystems work — inodes, links, and why deleting is really unlinking
