Fix "No space left on device" on Linux
Find which filesystem is full, then free the usual suspects: the package cache, the systemd journal and old container images. Then check inodes, because a disk can be "full" with gigabytes free.
df -h
df -i
sudo journalctl --vacuum-size=200M
sudo apt clean # Debian/Ubuntu/Mint
sudo dnf clean all # Fedora
sudo pacman -Sc # Arch
You will see the message in many shapes, but the underlying kernel error is always ENOSPC:
No space left on device
cp: error writing 'file.iso': No space left on device
bash: cannot create temp file for here-document: No space left on device
OSError: [Errno 28] No space left on device
What the error means
The kernel refused a write because the target filesystem has no free data blocks or no free inodes (every file and directory uses one inode). The error refers to the filesystem the file lives on, which is not necessarily /: /tmp, /boot, /var or a tmpfs can fill up on their own. Before deleting anything, identify which mount point is full.
df -h
Example output:
Filesystem Size Used Avail Use% Mounted on
/dev/nvme0n1p2 98G 98G 0 100% /
/dev/nvme0n1p1 1.1G 145M 950M 14% /boot/efi
tmpfs 7.8G 2.1M 7.8G 1% /tmp
A line at 100% (or with 0 in Avail) is your target. If nothing is at 100%, skip to the inode and deleted-file causes below.
Cause 1: the disk really is full
This is the most common case. Find the largest directories on the affected filesystem. The -x flag keeps du on one filesystem so it does not wander into other mounts.
sudo du -xh --max-depth=1 / 2>/dev/null | sort -h | tail -15
# drill into whatever is biggest, e.g.
sudo du -xh --max-depth=1 /var 2>/dev/null | sort -h | tail -15
If you prefer an interactive view, ncdu -x / (package ncdu on every major distro) does the same thing with a browsable list. Our find-largest-files script lists the biggest individual files, and the find cheat sheet covers queries like find / -xdev -size +1G.
Safe things to clean
| What | Command | Why it is safe |
|---|---|---|
| systemd journal | sudo journalctl --vacuum-size=200M | Deletes only archived journal files, oldest first |
| apt cache | sudo apt clean then sudo apt autoremove | Downloaded .deb files are re-downloadable; autoremove drops unused deps and old kernels |
| dnf cache | sudo dnf clean all | Metadata and packages are re-fetched on demand |
| pacman cache | sudo pacman -Sc or sudo paccache -rk2 | Keeps installed versions (or last two with paccache from pacman-contrib) |
| zypper cache | sudo zypper clean --all | Cached RPMs only |
| Docker / Podman | docker system prune / podman system prune | Removes stopped containers, dangling images and build cache (asks first) |
| Old snap revisions | sudo snap set system refresh.retain=2 | Keeps only two revisions of each snap going forward |
| Flatpak runtimes | flatpak uninstall --unused | Removes runtimes no app uses |
| User caches | du -sh ~/.cache, then delete what you recognise | Applications rebuild their cache |
Never rm files inside /var/lib/dpkg, /var/lib/rpm, /var/lib/pacman or /usr to make room. To shrink an active log that a service is writing to, truncate it with sudo truncate -s 0 /var/log/file.log instead of deleting it, otherwise you hit cause 3 below.
A full /boot
On systems with a separate small /boot partition, old kernels fill it and kernel updates fail with this error. On Debian and Ubuntu run sudo apt autoremove --purge; on Fedora, installonly_limit in /etc/dnf/dnf.conf controls how many kernels are kept (default 3). If apt itself is stuck because of the full partition, see dpkg returned an error code (1).
Cause 2: out of inodes (df -i shows 100%)
If df -h shows free space but writes still fail, check inode usage:
df -i
Example output:
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/nvme0n1p2 6553600 6553600 0 100% /
Millions of tiny files are the culprit: PHP session files, mail queues, cache directories, node_modules trees, or a runaway script creating temp files. Count files per directory to find them:
sudo find / -xdev -type f 2>/dev/null | cut -d/ -f2-3 | sort | uniq -c | sort -n | tail -10
Delete the small files you identify (for huge directories find /path -type f -delete is faster than rm *, which fails with Argument list too long). ext4 cannot add inodes after creation; if you regularly store millions of files, recreate the filesystem with a lower bytes-per-inode ratio (mkfs.ext4 -i 8192) or use XFS or Btrfs, which allocate inodes dynamically.
Cause 3: deleted files still held open
When you delete a file that a process still has open, the name disappears but the blocks stay allocated until the process closes it. This is why du totals can be far smaller than what df reports as used.
sudo lsof +L1
Example output:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NLINK NODE NAME
java 2214 app 7w REG 259,2 21474836480 0 13107 /var/log/app/app.log (deleted)
Restart the owning service (sudo systemctl restart app.service) to release the space. If you cannot restart it, you can truncate the file through the process file descriptor: sudo truncate -s 0 /proc/2214/fd/7.
Cause 4: root-reserved blocks and Btrfs specifics
ext4 reserves 5% of blocks for root by default, so a normal user gets "No space left" while df still shows a few gigabytes. On a data-only disk you can lower the reservation: sudo tune2fs -m 1 /dev/sdXN. Keep the default on the root filesystem; it lets root services and you recover.
On Btrfs (default on Fedora and openSUSE), df is approximate. Use Btrfs's own tools, and remember snapshots hold on to deleted data:
sudo btrfs filesystem usage /
sudo snapper list # openSUSE: snapshots created by zypper
sudo btrfs balance start -dusage=50 / # repacks half-empty data chunks
On openSUSE, delete old snapshots with sudo snapper delete <number> rather than removing subvolumes by hand.
Distro-specific notes
- Ubuntu / Mint: large consumers are usually
/var/lib/snapd(Ubuntu),/var/cache/aptand old kernels. Mint disables Snap, so check Flatpak in/var/lib/flatpakinstead. - Fedora:
/var/cache/libdnf5and/var/lib/flatpak; Btrfs root and/homeshare one pool, so filling home fills root. - Arch:
/var/cache/pacman/pkggrows forever unless you enablepaccache.timerfrom pacman-contrib. - openSUSE: snapper snapshots under
/.snapshotsare the usual cause on Tumbleweed and Leap.
How to prevent it
- Cap the journal permanently: set
SystemMaxUse=500Min/etc/systemd/journald.confand runsudo systemctl restart systemd-journald. - Enable cache cleanup:
sudo systemctl enable --now paccache.timeron Arch, scheduledocker system pruneon container hosts. - Make sure logrotate is running (
systemctl status logrotate.timer) and that your applications log through it or the journal. - Monitor usage with a simple timer or your monitoring stack, alerting at 85% for both
df -handdf -i. See disk management for resizing partitions when you simply need more room.
Still not working?
If the filesystem flips to read-only after a full-disk event, follow Read-only file system. Check for I/O errors with sudo dmesg -T | grep -iE 'error|ext4|btrfs|xfs', and confirm you are writing where you think you are with df -h /path/you/write/to, which prints the filesystem that actually holds that path.
Frequently asked questions
Why does df show free space but I still get "No space left on device"?
Either the filesystem has run out of inodes (check df -i), you are writing to a different mount than you think, or the remaining space is the root-reserved 5% on ext4 that normal users cannot use.
I deleted big files but the space did not come back. Why?
A running process still has the file open, so the kernel keeps the blocks allocated. Find it with sudo lsof +L1 and restart that process or service.
Is it safe to delete files in /var/log?
Deleting rotated archives such as *.gz and *.1 is safe. For the systemd journal use journalctl --vacuum-size= instead of deleting files by hand, and truncate active logs rather than removing them.
How do I free space on a system that cannot even boot to a desktop?
Log in on a text console (Ctrl+Alt+F3) or boot recovery mode, then run sudo apt clean / sudo dnf clean all and sudo journalctl --vacuum-size=200M. Those usually free enough to log in normally.
Spotted a mistake or a command that no longer works? Send a correction — pages are re-checked when reports come in.