Root Cause Diagnosis
Accumulation of dead directories in /var/lib/docker/overlay2 occurs when the Docker daemon crashes, loses daemon state tracking, or experiences ungraceful container terminations before completing layer cleanup. Manually executing rm -rf /var/lib/docker/overlay2/* breaks the Docker daemon by destroying the active image layer database and local SQLite/bolt key-value stores located in /var/lib/docker/image/overlay2/imagedb/. This creates orphaned references between Docker’s internal layer graph metadata and the actual backing filesystem, causing future container instantiations to fail with missing driver layer errors.
Quick Fix
Run the native Docker system prune with the volume flag to safely unmount and remove all unreferenced overlay2 layer diffs:
docker system prune -a --volumes -f
If disk space is still unreleased, reboot or restart the Docker service to release orphaned, deleted file handles still held open by the kernel:
sudo systemctl restart docker
Step-by-Step Resolution
Step 1: Identify Dead and Orphaned Overlay2 Directories
Map active, registered Docker container/image layer IDs against existing directories on disk to identify true orphans.
- Find all active layer diff hashes registered by Docker:
sudo docker inspect $(sudo docker ps -a -q) | grep -i "WorkDir\|MergedDir" | awk '{print $2}' | tr -d '",' | awk -F'/' '{print $(NF-1)}' | sort -u > /tmp/active_layers.txt - List all layer directories present on disk:
sudo ls -1 /var/lib/docker/overlay2 | grep -v "l" | sort -u > /tmp/disk_layers.txt - Compare both lists to isolate orphaned directories present on disk but missing from Docker metadata:
comm -23 /tmp/disk_layers.txt /tmp/active_layers.txt > /tmp/dead_layers.txt cat /tmp/dead_layers.txt
Step 2: Unmount Stale Overlay Mount Points
Orphaned layer deletions fail or cause system-wide kernel panics if mount points are still active in the VFS layer.
- Check if any identified dead directory is actively mounted:
grep overlay /proc/mounts | grep -f /tmp/dead_layers.txt - Force unmount any active stale mount points:
for mnt in $(grep overlay /proc/mounts | grep -f /tmp/dead_layers.txt | awk '{print $2}'); do sudo umount -f "$mnt" done
Step 3: Stop the Docker Daemon Safely
To avoid race conditions and corruption of /var/lib/docker/link, stop the container runtime entirely before modifying storage directories directly.
sudo systemctl stop docker
sudo systemctl stop docker.socket
Step 4: Safely Remove Orphaned Directories
Remove only the specific orphaned layer directories verified in Step 1. Do not modify the /var/lib/docker/overlay2/l symlink directory directly.
- Delete isolated orphan directories using
xargs:cat /tmp/dead_layers.txt | while read layer; do if [ -n "$layer" ] && [ -d "/var/lib/docker/overlay2/$layer" ]; then sudo rm -rf "/var/lib/docker/overlay2/$layer" fi done - Rebuild missing dynamic directory symlinks in the shortened symlink lookup table (
/var/lib/docker/overlay2/l) by removing broken dangling symlinks:sudo find /var/lib/docker/overlay2/l -xtype l -delete
Step 5: Restart the Daemon and Verify Database Integrity
Start the daemon service and confirm database integrity across existing images and containers:
sudo systemctl start docker
sudo docker info
sudo docker ps -a
Why This Fails for Some Users
- Active Systemd/Containerd Storage Driver Mismatch: On systems running Kubernetes or containerd independently alongside Docker,
containerdmanages its own overlay2 directories under /var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/. Deleting directories under/var/lib/docker/overlay2does not free disk space used by Kubernetes pods running on containerd. - XFS/Ext4
d_typeSupport Missing: Older Linux kernels or legacy filesystems formatted withoutftype=1prevent overlay2 from tracking file types properly. When clearing directories on systems withftype=0, Docker fails to rebuild layer structures upon daemon start. Verifyd_typesupport withxfs_info /var/lib/docker | grep ftype. - Stuck Open File Handles (
EBUSYErrors): If a process inside a crashed container hangs or holds locks on files within an overlay diff directory,rm -rfreturnsDevice or resource busy. You must identify and terminate the blocking process usingsudo lsof +D /var/lib/docker/overlay2/<layer_id>before the directory can be unlinked. - RHEL/CentOS SELinux Context Corruption: On RHEL/CentOS systems with SELinux in
Enforcingmode, manual file operations in/var/lib/docker/overlay2strip required security contexts (container_var_lib_t). After manual cleanup, you must restore contexts before starting containers:sudo restorecon -R -v /var/lib/docker/overlay2