This error occurs when Docker's devicemapper thin pool is running critically low on storage space. Docker enforces a minimum free space threshold to prevent data corruption. The fix involves cleaning up Docker resources, extending the thin pool, or migrating to the overlay2 storage driver.
The "Thin Pool has X free data blocks which is less than minimum required Y free data blocks" error indicates that Docker's devicemapper storage driver has detected critically low space in the thin provisioned storage pool. Docker maintains a safety threshold (configurable via `dm.min_free_space`, defaulting to 10%) to prevent operations when free space drops too low, protecting against potential data corruption. The devicemapper driver uses Linux's device mapper thin provisioning (dm-thinp) subsystem to create copy-on-write snapshots for container storage. Every container layer, image, and volume consumes blocks from this shared thin pool. When the free block count falls below the minimum required threshold, Docker refuses to allocate new storage to protect existing data. This error commonly appears on RHEL/CentOS systems, older Amazon Linux AMIs, and legacy Docker installations where devicemapper was the default storage driver. The devicemapper driver was deprecated in Docker 25.0 (January 2024), and Docker now recommends using overlay2 instead.
First, assess the current state of your thin pool to understand how severe the situation is:
# Check Docker storage driver info
docker info | grep -A 20 "Storage Driver"Key values to look for:
- Data Space Used / Data Space Total: Shows how much of the thin pool is consumed
- Thin Pool Minimum Free Space: The threshold that triggers this error (default 10%)
Also check the thin pool directly with LVM tools:
# View logical volumes and usage percentage
sudo lvs
# Get more detailed information
sudo lvs -a -o +devicesExample output showing a nearly full pool:
LV VG Attr LSize Pool Origin Data% Meta%
docker-pool docker twi-a-t--- 100.00g 92.50 45.00Remove stopped containers, unused images, and orphaned volumes to free space:
# Remove stopped containers
docker container prune -f
# Remove unused images (dangling only)
docker image prune -f
# Remove ALL unused images (including tagged ones not in use)
docker image prune -a -f
# Remove unused volumes (careful - may delete data!)
docker volume prune -f
# Remove unused networks
docker network prune -f
# Or clean everything at once (recommended)
docker system prune -a --volumes -fCheck how much space was recovered:
docker system df
docker info | grep "Data Space"Note: With devicemapper, pruning may not immediately free thin pool blocks. Restart Docker to force block reclamation:
sudo systemctl restart dockerThe devicemapper driver may not automatically reclaim blocks from deleted files. Force reclamation using fstrim:
# Run fstrim on all running containers to discard unused blocks
sudo sh -c "docker ps -q | xargs docker inspect --format='{{ .State.Pid }}' | xargs -IZ fstrim /proc/Z/root/"This command:
1. Gets the PID of each running container
2. Runs fstrim on the container's root filesystem
3. Discards unused blocks back to the thin pool
For a more aggressive cleanup when Docker is responsive:
# Run fstrim on the host filesystem too
sudo fstrim -avIf pruning doesn't recover enough space due to orphaned or fragmented layers, consolidate images by saving and reloading them:
# List images to identify what to keep
docker images
# Save important images to tar files
docker save -o myapp.tar myapp:latest
docker save -o nginx.tar nginx:alpine
# Remove all images
docker rmi $(docker images -q) -f
# Reload the images you need
docker load -i myapp.tar
docker load -i nginx.tar
# Clean up tar files
rm *.tarThis creates fresh, consolidated image layers without orphaned intermediate data.
Check if your volume group has free space to extend the thin pool:
# Check volume group free space
sudo vgsIf there's free space (VFree column), extend the thin pool:
# Find your thin pool name
sudo lvs -a | grep -i pool
# Extend the thin pool to use all free space
sudo lvextend -l+100%FREE /dev/docker/thinpool
# Or extend by a specific amount
sudo lvextend -L+20G /dev/docker/thinpoolAfter extending, restart Docker and verify:
sudo systemctl restart docker
docker info | grep "Data Space"Common thin pool paths vary by setup:
- /dev/docker/thinpool
- /dev/mapper/docker-pool
- /dev/mapper/docker-thinpool
If the volume group itself is full, add a new disk or partition:
# Create physical volume on new disk (WARNING: destroys all data on disk)
sudo pvcreate /dev/sdX
# Add the physical volume to the docker volume group
sudo vgextend docker /dev/sdX
# Now extend the thin pool
sudo lvextend -l+100%FREE /dev/docker/thinpool
# Restart Docker
sudo systemctl restart dockerFor AWS/cloud environments:
1. Attach a new EBS volume in the AWS console
2. Find the new device: lsblk
3. Create physical volume: sudo pvcreate /dev/xvdf
4. Extend volume group: sudo vgextend docker /dev/xvdf
5. Extend thin pool: sudo lvextend -l+100%FREE docker/thinpool
Enable automatic thin pool extension to prevent this error in the future:
# Create or edit the LVM profile for Docker
sudo vi /etc/lvm/profile/docker-thinpool.profileAdd the following configuration:
activation {
thin_pool_autoextend_threshold=80
thin_pool_autoextend_percent=20
}This automatically extends the pool by 20% when usage reaches 80%.
Apply the profile to your thin pool:
# Apply the profile (adjust path to match your thin pool)
sudo lvchange --metadataprofile docker-thinpool docker/thinpool
# Verify the profile is applied
sudo lvs -o+lv_profileNote: Autoextend only works if the volume group has free space available.
As a temporary measure, you can lower Docker's minimum free space threshold to allow operations to continue:
# Stop Docker
sudo systemctl stop dockerEdit or create /etc/docker/daemon.json:
{
"storage-opts": [
"dm.min_free_space=5%"
]
}Restart Docker:
sudo systemctl start dockerWarning: Lowering this threshold increases the risk of thin pool exhaustion and potential data corruption. Use this only as a temporary measure while implementing a proper fix (cleanup, extension, or migration).
The devicemapper driver is deprecated. Migrating to overlay2 eliminates thin pool issues entirely and provides better performance:
Warning: This process removes all existing images and containers. Back up important data first.
# Stop Docker
sudo systemctl stop docker
# Back up Docker data (optional but recommended)
sudo cp -au /var/lib/docker /var/lib/docker.backup
# Remove Docker data directory
sudo rm -rf /var/lib/docker
# Configure overlay2 storage driver
sudo vi /etc/docker/daemon.jsonSet the storage driver:
{
"storage-driver": "overlay2"
}Start Docker and verify:
sudo systemctl start docker
docker info | grep "Storage Driver"Should show: Storage Driver: overlay2
You'll need to re-pull all images after migration.
Requirements: overlay2 requires:
- Linux kernel 4.0+ (kernel 3.10.0-693+ on RHEL/CentOS 7)
- d_type=true on the filesystem (check with xfs_info /var/lib/docker)
Understanding dm.min_free_space: By default, Docker sets dm.min_free_space=10%, meaning operations fail when free space drops below 10% of the total thin pool size. The error message shows the actual free block count versus the minimum required. For example, "1234 free data blocks which is less than minimum required 16384" indicates 1234 blocks free but 16384 required (10% of pool).
Loopback vs direct-lvm modes: Loopback mode uses sparse files (/var/lib/docker/devicemapper/devicemapper/data) that can grow up to a configured limit but cannot shrink. Direct-lvm uses actual block devices and is required for production. Check your mode with docker info | grep "Data loop file" - if it shows a path, you're in loopback mode.
Why cleanup doesn't immediately free space: The devicemapper driver uses snapshot-style copy-on-write. Deleting a container or image marks blocks as unused but doesn't immediately release them. A Docker restart or fstrim operation may be needed to actually reclaim blocks.
AWS ECS specific considerations: AWS ECS instances using Amazon Linux 1 or 2 with devicemapper default to a 12GB xvdcz volume for Docker storage. This fills quickly with multiple container deployments. Solutions:
1. Use .ebextensions to configure larger storage in Elastic Beanstalk
2. Modify the ECS agent configuration: ECS_ENGINE_TASK_CLEANUP_WAIT_DURATION=1h
3. Consider using ECS with AL2023 which defaults to overlay2
Monitoring recommendations: Set up monitoring to catch low space before it causes failures:
#!/bin/bash
# Add to cron or monitoring system
USAGE=$(sudo lvs --noheadings -o data_percent docker/thinpool 2>/dev/null | tr -d ' ')
if [ ! -z "$USAGE" ] && (( $(echo "$USAGE > 80" | bc -l) )); then
echo "WARNING: Docker thin pool at $USAGE%"
fiWhen to completely reset Docker: If the thin pool is severely fragmented or corrupted (Docker hangs even after extension), a clean reset may be faster:
1. sudo systemctl stop docker
2. sudo rm -rf /var/lib/docker
3. Configure overlay2 in /etc/docker/daemon.json
4. sudo systemctl start docker
5. Re-pull required images
unable to configure the Docker daemon with file /etc/docker/daemon.json
How to fix 'unable to configure the Docker daemon with file daemon.json' in Docker
docker: Error response from daemon: OCI runtime create failed: container_linux.go: starting container process caused: exec: "/docker-entrypoint.sh": stat /docker-entrypoint.sh: no such file or directory
How to fix 'exec: entrypoint.sh: no such file or directory' in Docker
image operating system "linux" cannot be used on this platform
How to fix 'image operating system linux cannot be used on this platform' in Docker
dockerfile parse error line 5: unknown instruction: RRUN
How to fix 'unknown instruction' Dockerfile parse error in Docker
manifest unknown: manifest unknown
How to fix 'manifest unknown' in Docker