Linux "No Space Left on Device" Error Despite df -h Showing Free Disk Space (Inodes Full)
"No space left on device" while df -h clearly shows available disk space means you've run out of inodes, not actual storage blocks — Linux filesystems have a separate, fixed limit on the total number of files and directories they can hold, independent of how much raw disk space those files actually consume.
The Problem
Creating a new file fails with a disk-space-sounding error, even though there's plenty of free space by the usual measure:
touch newfile.txt
touch: cannot touch 'newfile.txt': No space left on device
df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 50G 12G 36G 25% /
25% disk usage with plenty of available space, yet the system insists there's no space left — this specific combination is the clearest signal of inode exhaustion rather than genuine disk space exhaustion.
Why It Happens
Every file and directory on a Linux filesystem requires an inode — a data structure storing metadata about that file (permissions, ownership, timestamps, and pointers to the actual data blocks). Most filesystems allocate a fixed number of inodes when the filesystem is first created, and this number is independent of the filesystem's total storage capacity. Common causes of exhausting them:
- An application or process creating an extremely large number of very small files — session files, cache files, log entries stored as individual files, temporary files — which can exhaust available inodes long before the underlying disk space itself fills up, since each file consumes one inode regardless of how small it is
- A misbehaving process caught in a loop that continuously creates new small files without cleaning up old ones, a bug that specifically manifests as inode exhaustion rather than disk space exhaustion precisely because the files themselves are individually tiny
- A filesystem originally provisioned with a relatively low inode count for its size, if it was formatted with non-default options optimized for fewer, larger files rather than the actual workload it ended up hosting
The Fix
First, confirm inode exhaustion is genuinely the cause by checking inode usage specifically, using the same df command but with the -i flag instead of -h:
df -i
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/sda1 3276800 3276800 0 100% /
100% inode usage, even with substantial free disk space by the normal block-based measure, confirms this diagnosis definitively.
Identify which directory contains the excessive number of small files, since the fix requires finding and addressing the actual source rather than just knowing inodes overall are exhausted:
for i in /*; do echo $i; find $i | wc -l; done 2>/dev/null | paste - -
This roughly counts files under each top-level directory, letting you narrow down which specific area of the filesystem has an unusually large file count. Repeat this process on the identified directory's own subdirectories to narrow down further, until you locate the specific directory responsible.
Once identified, clean up the excessive files if they're genuinely disposable (old cache files, old session files, accumulated logs stored individually rather than rotated):
find /path/to/culprit -type f -mtime +30 -delete
This deletes files older than 30 days in the identified location — adjust the specific criteria based on what's actually safe to remove for your particular situation, and always verify with a dry run (using find ... -mtime +30 without -delete first, just to see what would be matched) before actually deleting anything in a production environment.
If the root cause is an application generating excessive small files as part of its normal, ongoing operation (rather than a one-time cleanup being sufficient), address the underlying pattern — configure the application to use fewer, larger files (a database or a single log file with rotation, rather than one file per event), or implement automatic cleanup of old files as part of its regular operation, rather than needing manual intervention each time inodes fill up again.
Still Not Working?
If you've cleaned up files but inode usage doesn't seem to decrease correspondingly, check whether the deleted files are still being held open by a running process, similar to the analogous situation with disk block space — an open file handle to a deleted file still consumes its inode until every process holding it open closes it, exactly mirroring the "deleted but still holds disk space" pattern covered in disk block exhaustion troubleshooting, just manifesting through inode count instead of block usage:
lsof +L1