No space left on device: find what is filling your Linux disk
Fix "No space left on device" on Linux: find the biggest directories and files, free space safely, and handle the cases where df says there is space.
by OhSudo ·
You run a command, a deploy, a database write — and it fails with one of these:
write error: No space left on devicecp: error writing 'backup.tar.gz': No space left on deviceERROR: could not extend file "base/16384/2619": No space left on deviceThe kernel is telling you it can’t write any more data to a filesystem. Usually the disk really is full, but not always — this guide covers both cases. Don’t start deleting at random: first find which filesystem is full, then what is filling it.
TL;DR
df -h # which filesystem is full?df -i # ...or is it out of inodes?sudo du -xh --max-depth=1 / 2>/dev/null | sort -h # biggest directoriessudo find / -xdev -type f -size +100M -printf '%s %p\n' 2>/dev/null \ | sort -nr | head -20 | numfmt --to=iec --field=1 # biggest filessudo lsof +L1 # deleted files still holding space1. Find the full filesystem
df -hFilesystem Size Used Avail Use% Mounted on/dev/sda1 50G 49G 1.1G 98% /tmpfs 1.0G 0 1.0G 0% /dev/shmLook at Use% and Mounted on. A server often has several filesystems (/, /var, /home, a data disk), and only one of them is full. Everything below targets that mount point. To check the filesystem behind a specific path:
df -h /var/lib/postgresql2. Rule out inodes
Every file uses one inode, and a filesystem has a fixed number of them. Millions of tiny files — session files, mail queues, cache entries — can use up all inodes while df -h still shows free space. You get exactly the same “No space left on device” error.
df -iIf IUse% is at or near 100%, count files per directory to find the culprit:
sudo find /var -xdev -type f | cut -d/ -f2-3 | sort | uniq -c | sort -n | tail3. Find the biggest directories
du adds up sizes per directory. -x stays on one filesystem (so it doesn’t count other mounts), and sort -h understands sizes like 4.5G:
sudo du -xh --max-depth=1 / 2>/dev/null | sort -hThen drill down into the biggest one, level by level:
sudo du -xh --max-depth=1 /var 2>/dev/null | sort -hsudo du -xh --max-depth=1 /var/log 2>/dev/null | sort -h2>/dev/null hides “Permission denied” noise; sudo makes sure nothing is skipped.
4. Find the biggest files
Sometimes it’s one huge file — a runaway log, a forgotten backup, an ISO in someone’s home directory:
sudo find / -xdev -type f -size +100M -printf '%s %p\n' 2>/dev/null \ | sort -nr | head -20 | numfmt --to=iec --field=1This prints the size in bytes and the path, sorts from biggest to smallest and converts sizes to a readable form. A simpler variant, if you just want a list:
sudo find / -xdev -type f -size +500M -exec ls -lh {} + 2>/dev/nullFor an interactive view, install ncdu (sudo apt install ncdu or sudo dnf install ncdu, from EPEL on RHEL) and run sudo ncdu -x /.
5. Free space safely
The usual suspects, and how to clean them without breaking anything:
| What | Where | Safe cleanup |
|---|---|---|
| Application logs | /var/log/<app>/ |
Delete old rotated files (*.1, *.gz); empty the current one with truncate (see below) |
| systemd journal | /var/log/journal/ |
sudo journalctl --vacuum-size=500M |
| Package cache | /var/cache/apt/ or /var/cache/dnf/ |
sudo apt clean or sudo dnf clean all |
| Old kernels | /boot, /usr/lib/modules |
sudo apt autoremove --purge or sudo dnf remove --oldinstallonly |
| Docker | /var/lib/docker/ |
docker system df to see, then docker image prune / docker builder prune |
| Old backups | /var/backups/, home directories |
Move them off the server, then delete |
Shell, we have a problem!
Never delete a log file that a service is still writing to — the space is not freed until the service closes it (see the next section). Empty it instead:
sudo truncate -s 0 /var/log/app/debug.log
And never run rm -rf on a path you haven’t read twice. A stray space in rm -rf / var/log/app deletes far more than logs.
6. “I deleted it, but df still says the disk is full”
On Linux, deleting a file only removes its name. If a process still has the file open, the data stays on disk until that process closes it — typically a log file deleted while the service keeps writing to it. Find such files with:
sudo lsof +L1The output shows the process (COMMAND, PID) and the deleted file. Restart or reload that service — for example sudo systemctl restart myapp — and the space comes back. If you can’t restart it, you can empty the file through the process’s file descriptor: sudo truncate -s 0 /proc/<PID>/fd/<FD>.
7. “df shows free space, but I still can’t write”
Three things to check, in this order:
- Inodes —
df -i(step 2). - Reserved blocks — ext4 keeps 5% of the space for
rootby default, so regular users get “No space left on device” whilerootcan still write. On a 1 TB data disk that’s 50 GB. See it withsudo tune2fs -l /dev/sdX1 | grep -i 'reserved block count'. - The wrong filesystem — the directory you write to may live on a different, smaller mount.
df -h <path>tells you which one.
Note
Ubuntu / Debian vs RHEL / Rocky / AlmaLinux: the commands in this article are the same on both families. What differs is where things are: the package cache is /var/cache/apt vs /var/cache/dnf, the main system log is /var/log/syslog vs /var/log/messages, and some RHEL installs put /var or /home on separate LVM volumes — df -h shows you which.
Prevent it next time
- Alert before it’s full: monitor disk usage and alert at 80–85%, not 100%.
- Rotate logs: make sure every application log is covered by
logrotate, with compression and a limit on the number of files. - Cap the journal: set
SystemMaxUse=1Gin the[Journal]section of/etc/systemd/journald.conf, thensudo systemctl restart systemd-journald. - Clean up Docker regularly: unused images and build cache grow quietly.
$ ./practice.sh
Practice this in the terminal
Open the Terminal Playground with this article’s scenario loaded. It is safe and runs in your browser.
Found a mistake? Let us know at contact@ohsudo.com.