Container Name Is Already in Use: Resolving the Conflict Error
Symptom: the name is taken
docker: Error response from daemon: Conflict. The container name "/my-app" is
already in use by container "a1b2c3d4e5f6...". You have to remove (or rename)
that container to be able to reuse that name.
One-line diagnosis: a container named my-app already exists — container names are globally unique. Note that "exists" ≠ "running" — a stopped container still holds its name, which is the most common blind spot around this error. The full container ID is right there in the message, so the fix is direct.
The quick fix (covers 80% of cases)
# Delete by the ID from the error (-f stops a running one first)
docker rm -f a1b2c3d4e5f6
# Or by name
docker rm -f my-app
# Confirm
docker ps -a | grep my-app
docker rm -f on a running container is stop + remove; volumes are unaffected — removing a container deletes its writable layer, while data in volumes survives. But if you wrote data into the writable layer without a volume, removing the container removes the data: run docker diff <name> first to check for files worth rescuing.
Four frequent scenarios
1. The previous docker run container is still there (most common)
Repeatedly running docker run --name my-app ... while debugging — the first container stopped but was never removed. What you want is "restart", not "create another":
docker start my-app # already exists → start, not run
docker logs -f my-app # see why it exited before
2. Compose project leftovers
Containers from docker compose up are named project + service (like app-my-app-1). You changed the config and want a rebuild, but the old container holds the name:
docker compose down # stop + remove all project containers (volumes kept unless --volumes)
docker compose up -d
docker compose stop only stops — containers remain, names held. When in doubt among down/stop/rm: choose down.
3. The restart policy resurrected it
Containers with --restart unless-stopped or always come back automatically after a host reboot. You think it's dead and try to create a new one while it's alive:
docker ps --filter "name=my-app" --format "{{.Names}}: {{.Status}}"
4. One-shot containers missing --rm
Debugging containers should vanish when done — add --rm and stop accumulating name squatters:
docker run --rm --name temp-test myapp/api:v1 ...
Don't want to delete? Rename the old one
Something in the old container worth keeping? Rename it out of the way:
docker rename my-app my-app-old
docker run --name my-app ... # the name is free now
Prevention
- Let compose manage long-lived services instead of manual
docker run --name— compose handles rebuilds itself - One-shot debug containers always get
--rm - CI/CD scripts start with
docker rm -f <name> 2>/dev/null || truefor idempotent deploys - Audit
docker ps -aregularly; clean containers stopped for over a week
Telling the neighboring errors apart
| Error | What's occupied | Guide |
|---|---|---|
| container name already in use | the container name | this post |
| port is already allocated | a host port | port conflict |
| Conflict. The network ... already exists | a compose network | docker network rm / compose down |
Name scoping: why the same name conflicts (or doesn't) across contexts
Docker names are per-scope unique: container names are unique per daemon (two compose projects both naming their container "app" collide on a shared daemon — the compose prefix convention project-service-1 exists exactly for this), while in a Swarm/Kubernetes world, names namespace differently (compose projects isolate; plain docker run shares one namespace). The habits that prevent recurrence: unique project names per checkout (COMPOSE_PROJECT_NAME, or directory-name awareness — two clones of the same repo in different directories silently share or collide), --name only for long-lived services you reference (never for CI throwaways — random names are a feature), and container_name in compose files set only when something external must address it (omitting it lets compose namespace freely). The name conflict is almost always two projects assuming they are alone on the daemon.
CI ephemeral runners: the conflict pattern that eats builds
The classic CI failure: parallel jobs each docker run mytool --name worker — second job dies with name-conflict because the daemon is shared. The patterns in order of preference: no name at all (reference by container ID the script captures), unique names per job (--name worker-$CI_JOB_ID), or run --rm everywhere so names release immediately (the forgotten --rm is the zombie that holds the name past job end). The diagnostic one-liner when a CI name-conflict appears: docker ps -a --filter name=worker with a format string — the -a catches Exited containers that still hold the name; every CI runner should run this before jobs if names are mandatory.
container_name: in Compose: the conflict amplifier
Setting container_name: my-app in a compose file disables Compose’s project-prefixed naming. Two checkouts of the same repo (or two stacks with the same hard-coded name) will always collide on one daemon. Prefer omitting container_name unless an external system must address a stable DNS/hostname; when you must keep it, pair it with an explicit name: / -p project so humans see which stack owns the name. The Run to Compose helper preserves --name when you paste a docker run line — review that field before saving the YAML into a shared daemon.
Idempotent cleanup one-liners
# Free a name without failing the script when it is already gone
docker rm -f my-app 2>/dev/null || true
# List every container (running or not) whose name contains a stem
docker ps -a --filter "name=my-app" --format '{{.ID}} {{.Names}} {{.Status}}'
Wire the first line at the top of CI jobs that insist on a fixed --name. Combine with --rm for interactive debug so the name releases when the shell exits.
Checklist
docker ps -a --filter name=<name>— who holds it? What state?- Want the old one back →
docker start; done with it →docker rm -f - Compose scenario →
docker compose downbefore up - Data to rescue in the old container?
docker diff/ back up first - Future debug containers get
--rm; long-lived services go to compose - Avoid hard-coded
container_nameunless an external caller needs it
Named volumes vs named containers
Freeing a container name does not free a volume with the same stem. After docker rm -f my-app, check docker volume ls for leftovers that still hold data you thought you deleted. Compose project prefixes usually keep volume names unique; hard-coded container_name without a matching volume naming strategy is how two stacks share a database volume by accident. When in doubt, docker inspect the volume’s mountpoint labels before the next up.
Triage notes
The quick fix comes before the four scenarios because the error message already carries the full container ID — a direct rm covers 80% of cases with no classification needed. The scenarios are ordered by frequency, and the point the article keeps repeating — existing ≠ running, since a stopped container still holds the name — is the most common blind spot around this error and the reason scenario 1 (you should start, not run another) exists. The closing table slices by which resource is held: the name, port, and network errors look alike, but the resource type dictates each triage path.
Provided by ToolVault. Related tools: Dockerfile Generator, Run to Compose, Linux Cheatsheet. Related reading: Docker port is already allocated, Docker disk cleanup. See the homepage for more developer tools.
Related Tools
Related Articles
Linux Crontab in Practice: Commands, Logs, and Debugging
Crontab beyond syntax: three must-know commands, /etc/cron.d vs user crontabs, five-step debugging, PATH/timezone/% escaping, MAILTO, and what to do when you need second-level scheduling.
docker run to docker-compose: The Complete Migration Guide (with Flag Map)
Migrate docker run commands to docker-compose.yml: five advantages of compose over raw run, a flag-by-flag mapping table (ports, volumes, env, restart, networks), the classic pitfalls (bare -e passthrough, anonymous volumes, --rm semantics), and an online converter that runs locally in your browser.
Permission denied (publickey): 6 Reasons Git Push Fails Over SSH (and the Fix for Each)
git clone or push rejected with Permission denied (publickey) fatal: Could not read from remote repository? Covers missing keygen, key not loaded in the agent, public key not added to GitHub/GitLab, multi-account key routing with ~/.ssh/config, deploy key limits, and wrong remote URLs — with ssh -v diagnostics.