The 'removal of container is already in progress' error occurs when Docker is already attempting to delete a container and you try to remove it again. Wait for the operation to complete, or restart Docker if the container is stuck in a zombie state.
The "removal of container is already in progress" error in Docker indicates that the Docker daemon has already begun the process of removing a container, and you've issued another command that attempts to delete or interact with the same container. This typically occurs due to a race condition in Docker's container lifecycle management. When you stop a container started with the `--rm` flag, Docker automatically queues the container for removal. If your script or another process simultaneously tries to remove the same container, Docker returns this conflict error because it cannot process multiple removal operations on the same container. The error is particularly common in CI/CD environments (like GitHub Actions with Docker-in-Docker), automated scripts that manage containers, and when using `docker-compose` where multiple services are being torn down simultaneously. In most cases, the container will be successfully removed shortlyβyou just need to wait or handle the race condition in your automation.
In most cases, the container removal is legitimately in progress and will complete shortly. Simply wait a few seconds and try again:
# Wait a moment for the removal to complete
sleep 5
# Check if the container still exists
docker ps -a --filter "name=mycontainer"
# If still there, try removing again
docker rm mycontainerFor scripts, add retry logic with a delay:
# Retry removal with backoff
for i in 1 2 3 4 5; do
docker rm mycontainer 2>/dev/null && break
echo "Attempt $i failed, waiting..."
sleep $((i * 2))
doneExamine the container's current state to understand what's happening:
# List all containers including those being removed
docker ps -a
# Check container details
docker inspect mycontainer
# Look for 'Status' and 'State' in the output
docker inspect --format='{{.State.Status}}' mycontainerIf the status shows "removing" or "removal in progress", the daemon is actively working on it. If it's been stuck for a long time, proceed to the next steps.
Try force-removing the container to override the in-progress state:
# Force remove by name
docker rm -f mycontainer
# Force remove by container ID
docker rm -f abc123def456
# If that fails, try stopping first then removing
docker stop mycontainer && docker rm mycontainerThe -f flag sends a SIGKILL signal and forces removal, which can break through some stuck states.
If the container is stuck in a zombie state, restarting Docker often resolves it:
# Linux with systemd
sudo systemctl restart docker
# Or using service command
sudo service docker restart
# macOS/Windows Docker Desktop
# Use the Docker Desktop UI to restart, or:
# macOS: killall Docker && open /Applications/Docker.app
# Windows: Restart-Service docker (PowerShell as Admin)After restarting, the stuck container should either complete removal or become removable:
# Check status after restart
docker ps -a
# Try removing again
docker rm mycontainerIf you get "device or resource busy" errors, identify what's holding the container:
# Find what's using the container's overlay filesystem
sudo lsof +D /var/lib/docker/overlay2/
# Or check for processes using container directories
sudo fuser -v /var/lib/docker/containers/<CONTAINER_ID>/
# Look for processes that might be accessing mounted volumes
ps aux | grep -i dockerCommon culprits include:
- nginx or other servers with open file handles
- Log collection agents reading container logs
- Monitoring tools inspecting container filesystems
Stop these processes, then retry removal.
For persistent zombie containers when all else fails, manually remove the container directory:
# WARNING: This is a last resort - can cause data loss
# Stop Docker first
sudo systemctl stop docker
# Remove the container directory
sudo rm -rf /var/lib/docker/containers/<CONTAINER_ID>
# Start Docker
sudo systemctl start docker
# Verify container is gone
docker ps -aImportant: Only do this if:
- The container is truly stuck and other methods failed
- You don't need any data from the container
- You've stopped Docker before removing files
To prevent this error in automation, handle the race condition gracefully:
# Check container state before removal
container_state=$(docker inspect --format='{{.State.Status}}' mycontainer 2>/dev/null)
case "$container_state" in
"running")
docker stop mycontainer
docker rm mycontainer
;;
"exited"|"created"|"dead")
docker rm mycontainer
;;
"removing")
echo "Container removal already in progress, waiting..."
while docker ps -a --format '{{.Names}}' | grep -q "^mycontainer$"; do
sleep 1
done
;;
*)
echo "Container does not exist or unknown state"
;;
esacFor docker-compose, use error handling:
# Ignore removal-in-progress errors during down
docker-compose down 2>&1 | grep -v "removal of container.*already in progress" || trueWhen using docker-compose, properly clean up to avoid conflicts:
# Remove orphan containers from changed compose files
docker-compose down --remove-orphans
# Force removal of volumes too
docker-compose down -v --remove-orphans
# Clean up all stopped containers
docker container prune -f
# Nuclear option: remove all containers for this compose project
docker-compose rm -f -s -vThe --remove-orphans flag is especially important when you've renamed or removed services from your compose file.
### Understanding the Race Condition
The removal-in-progress error is fundamentally a race condition in Docker's container lifecycle. When you use docker run --rm, Docker schedules container removal immediately after the container stops. If your script then calls docker rm or docker-compose down, both operations race to remove the same container.
The Docker Engine API returns HTTP 400 with "removal of container name is already in progress" when it detects this conflict. This behavior was documented in the API to prevent undefined behavior from concurrent removals.
### CI/CD Best Practices
In GitHub Actions and other CI environments, this error is common due to the asynchronous nature of container management:
# GitHub Actions example with proper cleanup
- name: Stop containers
run: |
docker stop mycontainer || true
# Wait for --rm to finish if applicable
sleep 2
docker rm mycontainer 2>/dev/null || trueConsider using docker wait instead of docker stop when you need to ensure the container has fully exited:
# Wait for container to exit (blocks until stopped)
docker wait mycontainer
# Container is now fully stopped, safe to remove
docker rm mycontainer### Zombie Container Recovery
Containers can become zombies (stuck in "Removal In Progress" indefinitely) due to:
1. Filesystem issues: Long filenames in the container can cause lstat to fail during cleanup
2. Time sync daemons: ntpd or chronyd can hold file descriptors in container filesystems
3. Storage driver bugs: Issues with overlay2 or devicemapper can prevent layer removal
For filesystem issues, you may need to manually clean up the problematic files:
# Find files with extremely long names
sudo find /var/lib/docker/containers/<ID> -name "*" -print 2>&1 | grep "File name too long"
# Remove the container directory after stopping Docker
sudo systemctl stop docker
sudo rm -rf /var/lib/docker/containers/<ID>
sudo systemctl start docker### Docker Compose Pull Request #10136
The Docker Compose team addressed this issue by modifying how Compose handles orphan containers. Compose now ignores "conflict" errors (HTTP 409) when a removal is already in progress, treating it the same as "not found"βsince the end result (container gone) is the same.
If you're on an older version of Docker Compose, upgrade to get this fix:
# Check compose version
docker-compose version
# Update Docker Compose (Linux)
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose### Alternative: Use Container Labels for Cleanup
Instead of relying on container names, use labels for more robust cleanup:
# Create container with labels
docker run -d --label app=myapp --label env=test myimage
# Remove all containers matching labels (regardless of state)
docker rm -f $(docker ps -aq --filter "label=app=myapp")This approach avoids name conflicts entirely and allows for more flexible container management.
dockerfile 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