TL;DR: Another process is listening on the host port you asked for. Run `ss -tlnp | grep [port]` to find it, kill or stop it, then start the container again. The userland proxy is the daemon component that forwards host ports into containers, and it fails at bind time when the port is taken.

## The error

```text
driver failed programming external connectivity on endpoint web: Error starting userland proxy: listen tcp4 the all-interfaces address:80: bind: address already in use
```

## Fix it

1. Find the port from the error message (80 in the example).
2. Find the holder:
   `sudo ss -tlnp | grep ':80 '`
   Expected: a process name and PID. Common culprits: apache2, nginx, another docker-proxy, Skype on Windows.
3. Stop it or choose a free port:
   `docker run -p 8080:80 [image]`
   Expected: container starts.
4. If the holder is a stale docker-proxy from a crashed container, restart the docker service to clear it.

## When this applies
- Published ports failing with the userland proxy message
- Port 80/443 conflicts with a host web server

## When this does NOT apply
- "Bind for the all-interfaces address:X failed: port is already allocated" (earlier check, same fix though)
- No ports published (then this error cannot occur; look elsewhere)

## Versions
All Docker versions on Linux. Docker Desktop routes through the VM but surfaces the same message.

## Why it happens
With the default iptables setup, docker-proxy (the userland proxy) binds the host port to forward traffic into the container's network namespace. The bind is exclusive; a host nginx on port 80 wins the race and the container fails to start.

## Edge cases
- Disabling the userland proxy (`"userland-proxy": false` in daemon.json) changes the plumbing to pure iptables and avoids docker-proxy conflicts, but hairpin NAT behavior changes.
- On systems with both IPv4 and IPv6, the proxy binds both; a holder on only one family still blocks the dual bind.
- `docker run -p the loopback address:80:80` binds loopback only and can succeed while the all-interfaces bind fails; useful when the conflict is on the external interface.
