The Error
You run docker rmi <image> to free up disk space, and Docker throws this back at you:
Error response from daemon: conflict: unable to delete a1b2c3d4e5f6 (must be forced) - image is being used by stopped container 9f8e7d6c5b4a
The container is stopped โ not running โ yet Docker refuses. This confuses a lot of people. The assumption is that stopped containers don't hold resources. They do: a stopped container keeps its layer references on disk until you explicitly delete it.
Why This Happens
Docker images are stacks of read-only layers. When you spin up a container from an image, Docker adds a thin writable layer on top. Stop the container, and that layer โ along with its reference back to the original image โ sits on disk until you run docker rm.
The dependency chain is simple: image โ container (stopped). Docker won't yank an image out from under a container, even a dead one. It's protecting you from a dangling writable layer with nowhere to point.
Quick Fix: Remove the Blocking Container First
Find which container is holding the image:
docker ps -a --filter ancestor=<image_name_or_id> --format "table {{.ID}}\t{{.Names}}\t{{.Status}}"
Or look up the specific container ID from the error message directly:
docker inspect 9f8e7d6c5b4a --format '{{.Name}} โ {{.State.Status}}'
Once you've confirmed it's safe to delete:
docker rm 9f8e7d6c5b4a
docker rmi <image_name_or_id>
Done. Removing the container drops the reference, and rmi goes through cleanly.
When You Have Many Stopped Containers
After a day of iterating builds or running a CI pipeline, docker ps -a can easily list 50โ100 stopped containers, each holding a reference to its source image. Removing them one by one isn't practical. Wipe them all at once:
# Remove all stopped containers
docker container prune
# Skip the confirmation prompt
docker container prune -f
Then retry the image removal:
docker rmi <image_name_or_id>
Nuclear Option: Force Delete the Image
Skip the two-step process entirely with -f:
docker rmi -f <image_name_or_id>
What -f actually does: it untags and removes the image, but the stopped container's writable layer stays behind as a dangling reference. The container still appears in docker ps -a, now pointing at a broken image. That ghost entry can cause confusion down the line. Use force only during a full teardown โ for normal cleanup, the two-step approach is cleaner.
Full System Cleanup
Want to wipe everything unused in one shot? docker system prune handles stopped containers, dangling images, unused networks, and build cache together:
# Safe: removes only unused/dangling resources
docker system prune
# Aggressive: also removes images not used by any running container
docker system prune -a
# Skip confirmation
docker system prune -a -f
Watch out with -a. It pulls cached base images too โ things like node:20-alpine or python:3.12-slim that took time to pull. You'll re-download them on the next build. Run -a only when you genuinely want a clean slate.
Targeted Cleanup by Component
# Remove all stopped containers
docker container prune -f
# Remove dangling images (untagged, <none>:<none>)
docker image prune
# Remove all unused images
docker image prune -a
# Remove unused volumes
docker volume prune -f
# Remove unused networks
docker network prune -f
Verify the Fix
Confirm both the container and image are actually gone:
# Should return nothing
docker ps -a | grep 9f8e7d6c5b4a
# Should return nothing
docker images | grep <image_name>
# Check for leftover dangling images
docker images -f dangling=true
Seeing <none>:<none> entries in that last command? Clean them up:
docker image prune -f
Prevent This From Piling Up
Build these habits into your workflow and you'll rarely hit this error again:
- Use
--rmfor throwaway containers โ they auto-delete on exit:docker run --rm myimage - In CI pipelines, add
docker system prune -fas a post-build step before the job finishes - Tear down Compose projects with
docker compose down --rmi allinstead of plaindocker compose downโ it removes containers and images in one command - On long-running build servers, schedule a weekly
docker system prune -a -fvia cron; left unchecked, Docker can consume 20โ40 GB of disk in a month
Summary
image is being used by stopped container means a container record still exists on disk and holds a reference to that image. The fix: docker rm <container_id>, then docker rmi <image>. Cleaning up a pile of them? docker container prune followed by docker image prune does the job in two commands.

