Docker port is already allocated: Finding and Freeing the Taken Port
Symptom: the container won't start — a port couldn't be handed out
# During docker run
docker: Error response from daemon: driver failed programming external
connectivity on endpoint ...: Bind for 0.0.0.0:8080 failed: port is already allocated.
# Or the lower-level form
Error starting userland proxy: listen tcp4 0.0.0.0:80: bind: address already in use
One-line diagnosis: the host port you're mapping to is already taken. Mind the subject — not the container-internal port (that side is NAT, repeats are fine), but the host port on the left side of -p.
Step one: is the squatter a container or a host process?
# Suspect 1: another container mapped the same port
docker ps --filter "publish=8080"
# Suspect 2: a regular process on the host (nginx, a local dev server...)
sudo ss -tlnp | grep :8080
Run both; whoever is listening becomes obvious. The remedies differ completely:
A container holds it:
docker ps -a --filter "publish=8080" # include stopped ones
docker rm -f <container-name-or-id> # remove the old container, port freed
docker stop <container-name> # or just stop it — that frees the port too
A host process holds it: either stop it (systemctl stop nginx) or rerun your container on a different port.
Frequent scenario 1: the compose config changed, the old container stayed
Compose manages containers by project name (default = directory name). Two common collisions:
- You edited
docker-compose.ymlports to "start another copy", but the containers from the previousdocker compose upare still there — rundocker compose downfirst; - Two different directories share a name (say both
app/): identical compose project names fight over containers and ports. Isolate with an explicit project name:
docker compose -p projectA up -d
Frequent scenario 2: container removed, port still held (stale docker-proxy)
Rarely, docker ps shows no occupant while ss shows a docker-proxy process listening — restarting the Docker service clears the leftover:
sudo systemctl restart docker
That's the last resort: all containers restart with it, so assess the impact first on production.
A counterintuitive detail: different bind addresses can coexist
docker run -p 127.0.0.1:8080:80 --name a ... # loopback only
docker run -p 192.168.1.5:8080:80 --name b ... # a specific NIC
The conflict check is on the "address + port" combination, not the port alone. 127.0.0.1:8080 conflicts with 0.0.0.0:8080 (the latter includes the former), but 127.0.0.1:8080 and 192.168.1.5:8080 can coexist. This detail saves you one round of "nobody is using it, why the conflict" — the invisible binding on the other side is usually a 0.0.0.0.
Relation to host-side EADDRINUSE
The same event from two viewpoints: your application process fails to listen on a taken port with EADDRINUSE; your container fails to map one with port is already allocated. The diagnostic flow is shared — see Port already in use: EADDRINUSE troubleshooting. The opposite direction, "can't connect to a port" (ECONNREFUSED), is a different problem entirely: ECONNREFUSED troubleshooting.
Checklist
docker ps --filter "publish=<port>"— does a container hold it?ss -tlnp | grep :<port>— does a host process hold it? (run both checks)- Old containers:
docker rm -f; compose scenarios:docker compose downfirst - Nobody visible but still failing?
systemctl restart dockerclears stale docker-proxy - Port reuse: 127.0.0.1 conflicts with 0.0.0.0, but not with a specific NIC IP
Provided by ToolVault. Related tools: Dockerfile Generator, CIDR Calculator, HTTP Status Codes. Related reading: Port already in use (EADDRINUSE), ECONNREFUSED troubleshooting. See the homepage for more developer tools.
Related Tools
Related Articles
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.
error:0308010C digital envelope routines::unsupported — Fixing Node 17+ Breakage in Older Projects
Node 17+ crashes webpack 4 builds with error:0308010C:digital envelope routines::unsupported because OpenSSL 3.0 removed MD4. Three fixes compared: --openssl-legacy-provider quick unblock, upgrading to webpack 5 as the real fix, and pinning Node 16 as a stopgap.
ECONNREFUSED: Connection Refused — 5 Causes Explained (Including Docker)
Node, Java, or curl reporting connect ECONNREFUSED 127.0.0.1:3306? It means nothing is listening on that port. Covers service not running, wrong port, 127.0.0.1-only binding, Docker container networking, and firewall REJECT rules — with ss/lsof diagnostic commands.