Linux No Space Left on Device: Check Inodes First
Diagnose Linux no space left on device errors with df, du, and inode checks. Find the full filesystem before deleting Docker data or resizing your VPS disk.
Your app says No space left on device. Your VPS dashboard says there is plenty of storage. Before you delete a Docker volume out of frustration, check what actually ran out.
Linux storage has more than one constraint. Free bytes matter, but so do inodes, mount boundaries, and files that a process still holds open after deletion. I would rather spend two minutes identifying the constraint than run a cleanup command that destroys the wrong data.
Quick answer: run df -h and df -i against the directory where the write failed. Then investigate that filesystem, not whichever directory looks big.
Start with the failing path
These examples target a Linux server with GNU coreutils. You need read access to the affected directory; inspecting other users’ files may require sudo.
Suppose your application writes under /srv/myapp. Replace that example with an existing directory on your server:
df -h /srv/myapp
df -i /srv/myapp
The first command reports block-space usage. The second reports inode usage: filesystem metadata records associated with files and directories. On filesystems with a fixed inode supply, a pile of tiny files can exhaust that supply before you run out of bytes.
Read Avail and Use% in the first result, then IFree and IUse% in the second. Plenty of free bytes plus no available inodes is a different incident from a disk full of video files.
Do not diagnose a mounted data disk by checking / alone. The directory argument makes df report the filesystem containing that path, as described in the GNU df documentation.
A real check, without a manufactured outage
During preparation for this article, I ran both checks on the filesystem containing this site’s repository. The block-space report showed 58% usage; the inode report showed 11% usage.
That is a useful boring result: neither counter was exhausted at the time of the check. It is not a benchmark, a simulated failure, or evidence about your server. We did not fill a production disk to demonstrate an error message.
The distinction matters because a guide should teach diagnosis, not imply every storage error has the same cause. Start with your own measurements.
If bytes are full, narrow the search
Use du to find which directory trees account for allocated space. The following command stays on one filesystem with -x and reports only the immediate children with --max-depth=1:
sudo du -x -h --max-depth=1 /srv
Choose the mount point or relevant directory revealed by df. Repeat inside the largest branch rather than scanning every disk attached to the machine.
On a large tree, du can generate substantial disk I/O. Run it deliberately, and expect changing files or permission errors to affect the result. A summary is an investigation aid, not a transactionally consistent snapshot.
Common candidates include application uploads, caches, old exports, and logs. Identify the owner and retention policy before deleting anything. If the application provides a supported cleanup command, that is usually preferable to removing files behind its back.
For Docker, begin with its own accounting:
docker system df
This does not account for every byte in arbitrary host bind mounts. It also does not authorize a prune. Do not use docker system prune --volumes as a generic disk repair command. A volume that is unused by a current container can still contain data you intended to keep.
If logs dominate, our Dozzle guide explains why viewing logs does not replace Docker log retention. Fix the producer or retention policy, not just today’s symptom.
If inodes are full, hunt for file counts
A cache containing millions of tiny files can look modest in a byte-based report. GNU du can summarize inode usage instead:
sudo du -x --inodes --max-depth=1 /srv
Follow the largest count into its subdirectories. Cache entries, abandoned session files, and application-generated temporary files are plausible suspects, not permission to delete those directories blindly.
I would pause or throttle the writer before cleaning a directory that is filling as fast as I can empty it. Otherwise, the cleanup becomes a race and the error returns immediately.
On ext4, inode availability is tied to how the filesystem was created. Other filesystems manage metadata differently, so do not assume that every filesystem has the same fixed-inode model. Check the filesystem type and its documentation before choosing a structural fix.
Resizing a virtual disk alone is not a complete recovery procedure. The partition, filesystem, and metadata limits still need the appropriate treatment for that storage layout.
If df and du disagree, look for open deleted files
Deleting a filename does not necessarily free its storage immediately. A process can retain an open file descriptor, and the underlying storage remains allocated until the remaining references are released.
If lsof is installed, this read-only check helps identify open files whose link count is below one:
sudo lsof +L1
Look for large deleted regular files on the affected filesystem. The listing may include unrelated entries, so match the process and device to the incident rather than restarting everything you see.
A controlled restart of the owning service can release its file descriptors. Prefer the service’s documented log-reopen mechanism when available, and assess downtime before restarting a database or reverse proxy.
Never truncate an arbitrary /proc/.../fd/... target just because a command from a forum promises instant space. That file descriptor might belong to data you cannot afford to corrupt.
Still failing? Check the actual write environment
Healthy block and inode counters do not rule out quotas, a full temporary filesystem, or an application writing somewhere other than the directory you checked. Containers can also write into their own writable layers rather than the bind mount you expected.
Find the exact failing path in the application’s error output. Check that path in the relevant mount namespace, inspect configured quotas if applicable, and distinguish No space left on device from permission or read-only-filesystem errors.
For a Docker application, reviewing its mounts is often more useful than increasing the VPS plan. Our Docker Compose basics cover the distinction between persistent volumes and bind mounts.
Keep recovery separate from prevention
After a supported cleanup, rerun both df checks and confirm the application can perform its intended write. Record what grew, why it grew, and which retention policy now limits it.
Monitor free bytes and inode availability on the filesystems that matter. Set thresholds according to workload and growth rate rather than treating one percentage as universal. Keep tested backups before making destructive changes.
A VPN does not recover disk space or prevent inode exhaustion. If you separately need outbound privacy on an administrative laptop, the following is an optional affiliate offer, not a tool required by this tutorial:
🚀NordVPN
Optional outbound privacy for your administrative device, separate from server disk recovery.
Affiliate link — we may earn a commission at no extra cost to you.
Your next step: pick the actual directory your app writes to and run the two df commands. Get the diagnosis first. The delete button can wait.
Stay in the loop 📬
Get self-hosting tutorials, tool reviews, and infrastructure tips delivered to your inbox. No spam, unsubscribe anytime.
Join 0 self-hosters. Free forever.