This error occurs when Docker detects an existing prune operation lock, often caused by interrupted SSH sessions, unresponsive containers, or containerd communication failures.
When you run `docker system prune` or any related prune command, Docker creates a lock to prevent multiple prune operations from running simultaneously. This safeguard ensures data integrity during cleanup operations. The error "a prune operation is already running" appears when Docker's daemon detects this lock is still active. However, in most cases, no actual prune operation is running. The lock typically persists due to: 1. **Interrupted operations**: If your SSH session disconnects mid-prune or the terminal closes unexpectedly, the lock may remain even though the operation stopped. 2. **Unresponsive containers**: A container that Docker cannot communicate with can cause the daemon to hang, leaving the lock in place. 3. **Containerd issues**: In some cases, the underlying container runtime (containerd) fails to respond to the Docker daemon, causing cleanup operations to stall indefinitely. This is a concurrency protection mechanism that has become stuck, not an indication of an actual ongoing operation.
Before taking action, verify whether a legitimate prune operation is in progress. Open a new terminal and run:
docker system infoWatch the "Images" and "Containers" counts. If they are decreasing over time, a prune operation is genuinely running. Wait for it to complete.
If the counts remain static, the lock is stale and you can proceed with the following fixes.
The simplest and most reliable fix is restarting the Docker service, which clears the stale lock:
On Linux with systemd:
sudo systemctl restart dockerOn older Linux systems:
sudo service docker restartOn macOS (Docker Desktop):
Click the Docker icon in the menu bar, then select "Restart Docker Desktop."
On Windows (Docker Desktop):
Right-click the Docker icon in the system tray and select "Restart."
After restarting, retry your prune command:
docker system pruneIf restarting Docker is not an option (e.g., production environment), identify containers that may be causing the hang:
Test container responsiveness:
docker ps -aTry inspecting each container. An unresponsive container will cause this command to hang:
docker inspect <container_id>Find the stuck container process:
ps aux | grep docker-containerd-shimKill the unresponsive container process:
sudo kill -9 <PID>Force remove the problematic container:
docker rm -f <container_id>After removing the unresponsive container, retry the prune operation.
If the prune operation was stuck while removing images, you may need to force-remove them manually:
docker rmi -f $(docker images -q --filter "dangling=true")Or to remove all unused images:
docker rmi -f $(docker images -aq)Warning: This removes all images not currently used by running containers. Only use this if you are comfortable re-pulling required images.
To avoid this error in the future:
Use the force flag to skip confirmation prompts:
docker system prune -fRun prune in a screen or tmux session to survive SSH disconnections:
screen -S docker-prune
docker system prune -a --volumes
# Detach with Ctrl+A, DFor CI/CD environments, use age filters to avoid conflicts:
docker system prune -f --filter "until=24h"This only removes resources older than 24 hours, reducing the chance of conflicts with active build operations.
### Understanding Docker's Prune Lock Mechanism
Docker uses a mutex lock at the daemon level to prevent concurrent prune operations. This is essential because prune operations involve:
- Iterating through all containers, images, networks, and volumes
- Checking dependencies between resources
- Removing resources in the correct order
Running multiple prune operations simultaneously could lead to race conditions or data corruption.
### Containerd Integration Issues
The Docker daemon communicates with containerd (the container runtime) for low-level container operations. When containerd becomes unresponsive (documented in containerd issue #2078), the daemon's goroutines can wait indefinitely. This manifests as a stuck prune operation even though no actual cleanup is happening.
To check containerd health:
sudo systemctl status containerd
sudo journalctl -u containerd -n 50### Production Environment Considerations
In production, restarting Docker stops all running containers. If you cannot restart Docker:
1. Identify the specific unresponsive container causing the hang
2. Use kill -9 on its containerd-shim process
3. Force-remove the container with docker rm -f
This surgical approach minimizes disruption while clearing the lock.
### Debugging with Stack Traces
To get detailed debugging information, send SIGUSR1 to the Docker daemon:
sudo kill -SIGUSR1 $(pidof dockerd)Check the Docker logs for stack traces that reveal where the daemon is stuck:
sudo journalctl -u docker -n 100dockerfile parse error line 5: unknown instruction: RRUN
How to fix 'unknown instruction' Dockerfile parse error in Docker
Error response from daemon: manifest for nginx:nonexistent not found: manifest unknown: manifest unknown
How to fix 'manifest for image:tag not found' in Docker
Error response from daemon: invalid reference format: repository name must be lowercase
How to fix 'repository name must be lowercase' in Docker
Error response from daemon: No such image
How to fix 'No such image' in Docker
Error response from daemon: Container is not running
How to fix 'Container is not running' when using docker exec