Docker Error Guide: 'bind: address already in use' — Port Conflict on Container Start
Fix 'bind: address already in use' in Docker: find the process or container holding the host port, free it or remap the published port, then restart.
- #docker
- #troubleshooting
- #errors
- #networking
Stuck on this Docker with AI error? Get the free incident triage checklist
A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.
Overview
Docker publishes a container port to the host by asking the kernel to bind() a listening socket on a host address and port. If something is already listening on that exact address:port, the kernel returns EADDRINUSE and Docker refuses to start the container. The message appears on docker run -p, docker start, or docker compose up:
Error response from daemon: driver failed programming external connectivity on endpoint web (a1b2...):
Bind for 0.0.0.0:8080 failed: port is already allocated
The lower-level variant surfaces the raw kernel error text:
docker: Error response from daemon: Ports are not available: exposing port TCP 0.0.0.0:8080 -> 0.0.0.0:0:
listen tcp 0.0.0.0:8080: bind: address already in use.
Symptoms
- A container exits immediately or never starts, and
docker ps -ashows it asCreatedorExited. docker compose upfails on one service while the rest come up.- The same image starts fine after you change the published host port.
docker start <container>fails even though it ran yesterday — because a second process grabbed the port in the meantime.
Common Root Causes
- Another container already publishes the same host port — a forgotten or duplicated
-p 8080:80. - A host process owns the port — a system nginx, a dev server, or a previously crashed app still holding the socket.
- Two Compose services map to the same host port — copy-paste in
docker-compose.yml. - A stopped container still holds the reservation — Docker’s userland proxy or a wedged
docker-proxyprocess kept the port allocated. - You restarted a service while the old instance was still shutting down, so both briefly want the port.
Diagnostic Workflow
First, ask Docker what it already has published:
docker ps --format 'table {{.Names}}\t{{.Ports}}'
Find the process actually listening on the host port (here 8080):
sudo ss -ltnp 'sport = :8080'
# or
sudo lsof -i :8080 -sTCP:LISTEN
If the listener is a container, inspect its port bindings:
docker inspect --format '{{json .NetworkSettings.Ports}}' <container>
If the process is docker-proxy, a container still owns the port — trace it back:
docker ps -a --filter "publish=8080"
Check daemon logs if the binding fails inconsistently:
journalctl -u docker --since '10 min ago' | grep -i 'bind\|already allocated'
Example Root Cause Analysis
A team reported Bind for 0.0.0.0:8080 failed: port is already allocated when running docker compose up api. docker ps showed no container on 8080, which pointed away from Docker. Running sudo ss -ltnp 'sport = :8080' returned:
LISTEN 0 128 0.0.0.0:8080 0.0.0.0:* users:(("java",pid=2417,fd=44))
A leftover Spring Boot dev process (PID 2417) from a manual test still held the port. It was not a container at all. Stopping that process with kill 2417 freed the socket, and docker compose up api succeeded immediately. The lesson: port is already allocated from Docker does not always mean another container — the conflict is at the host kernel level, so any host listener counts.
Prevention Best Practices
- Standardize host ports per environment and document them so two services never claim the same one.
- Bind to a specific interface (
-p 127.0.0.1:8080:80) for local-only services so they cannot collide with public listeners. - Prefer high, unique host ports in development and let a reverse proxy front them.
- In Compose, use variables like
${API_PORT:-8080}:80so conflicts are resolved by overriding one env var. - Always
docker compose down(not just Ctrl-C) so the old container releases its port before the next start. - Validate Dockerfiles and Compose port hygiene with the free Dockerfile validator.
Quick Command Reference
sudo ss -ltnp 'sport = :8080' # who holds the port
sudo lsof -i :8080 -sTCP:LISTEN # alternative lookup
docker ps --filter "publish=8080" # container publishing it
docker ps -a --filter "publish=8080" # including stopped ones
docker rm -f <container> # remove the conflicting container
docker run -p 8081:80 myapp:1.4.2 # remap to a free host port
Conclusion
bind: address already in use is a plain kernel EADDRINUSE: the host address:port you asked Docker to publish is already taken. Identify the real listener with ss/lsof, decide whether it is a container or a host process, then either free that port or remap your publish to an unused one. Standardizing ports and always tearing containers down cleanly keeps the conflict from returning. For more runtime fixes, see the Docker guides.
Fixed it? Get 500 Docker with AI & DevOps AI prompts — free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.
Stuck on this? Start guided troubleshooting
Open an interactive diagnostic session with this error already loaded. Work a step-by-step plan, record what each check returns, land on a root cause, and export a clean incident summary — no account needed to start.
Did this fix your issue?
Solved it a different way?
Share the fix that worked for you — reviewed, then published to help the next engineer.
That looks like it may contain a secret (key, token, password, or connection string). Please remove it — a note with a detected secret can’t be published.
Thanks — that helps. Published notes appear after a quick review.
Trending errors this week
The error guides other engineers are actually reading right now.
- 1mount: wrong fs type, bad option, bad superblock
- 2Docker 'failed to set up container networking': Fix the Bridge and IP Pool
- 3Docker 'failed to create shim task': How to Fix the containerd Runtime Error
- 4Transport endpoint is not connected
- 5modprobe: FATAL: Module not found
- 6mount: wrong fs type, bad option, bad superblock
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.