Docker Error Guide: 'driver failed programming external connectivity' — Port Publish Fails
Fix 'driver failed programming external connectivity on endpoint': a port already in use, a stale iptables rule, or a dead daemon. Free the port or restart Docker to recover.
- #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
A container fails to start because Docker cannot wire up its published port:
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
When you publish a port (-p 8080:8080), Docker’s network driver programs host firewall/NAT rules to forward that host port to the container. If it cannot — because the host port is already taken, a stale rule from a crashed container remains, or the daemon’s iptables state is inconsistent — it aborts with driver failed programming external connectivity. The trailing detail (usually port is already allocated or a Bind error) tells you why.
Symptoms
docker run -pordocker compose upfails naming an endpoint and a host port.- The tail reads
port is already allocatedorBind for 0.0.0.0:<port> failed. - A container that crashed left a port “allocated” even though nothing is listening.
- The same compose stack starts fine after a Docker daemon restart.
- Two services (or two Compose projects) try to publish the same host port.
Common Root Causes
- Host port already in use by another container or a non-Docker process (a local nginx, a dev server, systemd-resolved on 53).
- Stale NAT/iptables rule from a container that crashed or was killed uncleanly, leaving the port “allocated” in Docker’s view.
- Two containers publishing the same host port, often the same Compose service scaled or two projects colliding.
- Docker’s iptables state got out of sync after a firewall reload (
firewalld/ufw) flushed Docker’s chains. - Rootless/port-permission issues when binding privileged ports (<1024) without the right configuration.
Diagnostic Workflow
First, see what already holds the host port. Check Docker’s own view and the OS’s:
docker ps
sudo ss -ltnp | grep ':8080'
If ss shows a non-Docker process, that program owns the port. If it shows nothing but Docker still reports “allocated”, the culprit is a stale rule. List containers that publish the port:
docker ps -a --format '{{.Names}}\t{{.Ports}}' | grep 8080
Remove a stale/dead container holding the mapping:
docker rm -f <container>
If Docker’s iptables state is inconsistent, restarting the daemon reprograms the rules cleanly:
sudo systemctl restart docker
Choose a non-conflicting host port in Compose rather than fighting over one:
services:
web:
image: registry.example.com/myapp:1.4.2
ports:
- "8081:8080" # host 8081 -> container 8080
Then retry:
docker compose up -d
docker ps
Example Root Cause Analysis
A team ran two independent Compose stacks on the same host: an internal dashboard and a new API. Both docker-compose.yml files happened to publish - "8080:8080". The dashboard started at boot; when CI later deployed the API with docker compose up -d, it failed with driver failed programming external connectivity on endpoint api ...: Bind for 0.0.0.0:8080 failed: port is already allocated.
sudo ss -ltnp | grep ':8080' showed the dashboard’s docker-proxy already bound to host port 8080, confirming a straightforward collision rather than a stale rule. Because both stacks legitimately needed to be reachable, the fix was to remap the API to a free host port: - "8081:8080" in its Compose file, fronted by the reverse proxy. After docker compose up -d, both stacks ran side by side.
Separately, the team hit the stale-rule variant once when a container was killed with kill -9 on the daemon: Docker still considered 8080 allocated though ss showed nothing listening. There, docker rm -f of the dead container followed by sudo systemctl restart docker cleared the orphaned NAT rule.
Prevention Best Practices
- Assign unique host ports across stacks and document them; a small port map prevents most collisions.
- Check the port before publishing:
sudo ss -ltnp | grep ':<port>'in deploy scripts to fail fast with a clear message. - Clean up dead containers with
docker rm -f(anddocker container prune) so stale mappings do not linger. - Restart Docker after firewall reloads.
firewalld/ufwreloads can flush Docker’s iptables chains;systemctl restart dockerreprograms them. - Front services with a reverse proxy so only one host port (80/443) is published and internal services stay on the Docker network. See the Docker stack guides.
Quick Command Reference
# What holds the host port? (Docker + OS view)
docker ps
sudo ss -ltnp | grep ':8080'
# Which container publishes it?
docker ps -a --format '{{.Names}}\t{{.Ports}}' | grep 8080
# Remove a stale/dead container
docker rm -f <container>
# Reprogram Docker's iptables/NAT rules
sudo systemctl restart docker
Conclusion
driver failed programming external connectivity means Docker could not bind a published host port — usually because it is already allocated, or a stale NAT rule from a dead container remains. Use sudo ss -ltnp to find the real owner, remap to a free port in Compose, remove orphaned containers, and restart the daemon if its firewall state drifted. Unique host ports plus a port-availability check in your deploy flow keep this error from recurring.
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.