Fix "No space left on device" on Linux

Quick fix

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

WhatCommandWhy it is safe
systemd journalsudo journalctl --vacuum-size=200MDeletes only archived journal files, oldest first
apt cachesudo apt clean then sudo apt autoremoveDownloaded .deb files are re-downloadable; autoremove drops unused deps and old kernels
dnf cachesudo dnf clean allMetadata and packages are re-fetched on demand
pacman cachesudo pacman -Sc or sudo paccache -rk2Keeps installed versions (or last two with paccache from pacman-contrib)
zypper cachesudo zypper clean --allCached RPMs only
Docker / Podmandocker system prune / podman system pruneRemoves stopped containers, dangling images and build cache (asks first)
Old snap revisionssudo snap set system refresh.retain=2Keeps only two revisions of each snap going forward
Flatpak runtimesflatpak uninstall --unusedRemoves runtimes no app uses
User cachesdu -sh ~/.cache, then delete what you recogniseApplications rebuild their cache
Do not delete blindly

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/apt and old kernels. Mint disables Snap, so check Flatpak in /var/lib/flatpak instead.
  • Fedora: /var/cache/libdnf5 and /var/lib/flatpak; Btrfs root and /home share one pool, so filling home fills root.
  • Arch: /var/cache/pacman/pkg grows forever unless you enable paccache.timer from pacman-contrib.
  • openSUSE: snapper snapshots under /.snapshots are the usual cause on Tumbleweed and Leap.

How to prevent it

  • Cap the journal permanently: set SystemMaxUse=500M in /etc/systemd/journald.conf and run sudo systemctl restart systemd-journald.
  • Enable cache cleanup: sudo systemctl enable --now paccache.timer on Arch, schedule docker system prune on 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 -h and df -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.