Skip to content
DevOps AI ToolKit
Newsletter
All guides
Docker with AI By James Joyner IV · · 9 min read

Docker Error Guide: 'driver failed programming external connectivity' — Port Publish Fails

Quick answer

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.

Part of the Docker Container & Runtime Errors hub
  • #docker
  • #troubleshooting
  • #errors
  • #networking
Free toolkit

Fixing errors like this? Get 500 free DevOps AI prompts

500 copy-paste AI prompts for the stack you actually run — one PDF, free.

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 -p or docker compose up fails naming an endpoint and a host port.
  • The tail reads port is already allocated or Bind 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 (and docker container prune) so stale mappings do not linger.
  • Restart Docker after firewall reloads. firewalld/ufw reloads can flush Docker’s iptables chains; systemctl restart docker reprograms 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.

Free download · 368-page PDF

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.