Skip to content
ohsudo, Home
Docker & Containers

Docker "port is already allocated" and "ports are not available": find who has the port

Fix Docker "Bind for 0.0.0.0:8080 failed: port is already allocated" and "Ports are not available": find the container or process using it, and Windows reserved ports.

Beginner4 min readApplies to Docker Engine 20.10+ · Docker Desktop · Docker Compose v2 · Linux · Windows · macOS

by OhSudo ··

Checked on real software: Docker · November 2026How we check

Not sure this is your cause?Find it step by step: Container won't start →

Part of a learning path:Docker: from first container to production

docker: Error response from daemon: driver failed programming external connectivity on endpoint web (a1b2c3...): Bind for 0.0.0.0:8080 failed: port is already allocated.

And a close relative, with a different cause, common on Windows and Docker Desktop:

Error response from daemon: Ports are not available: exposing port TCP 0.0.0.0:8080 -> 127.0.0.1:0: listen tcp 0.0.0.0:8080: bind: An attempt was made to access a socket in a way forbidden by its access permissions.

Only one program can listen on one port at a time. Your -p 8080:80 asks for port 8080 on the host, and something already has it. The number on the right, inside the container, plays no part.

  1. docker run -p 8080:80wants host port 8080
  2. Host port 8080one listener at a time
  3. Already takenanother container, or a program on the host(breaks here)
-p 8080:80 asks for port 8080 on the host. Only one program can have it, and something already does; the port inside the container plays no part.

TL;DR

Terminal window
docker ps --filter publish=8080 # another container?
sudo ss -tlnp | grep ':8080 ' # another process? (Linux)

On Windows:

Terminal window
Get-NetTCPConnection -LocalPort 8080 -State Listen
netsh interface ipv4 show excludedportrange protocol=tcp

Stop what’s there, or publish on another port: -p 8081:80.

1. Another container

By far the most common, often a forgotten old run:

Terminal window
docker ps --filter publish=8080
CONTAINER ID IMAGE COMMAND PORTS NAMES
f3a91c2d7b10 nginx:1.27 "/docker-entrypoint.…" 0.0.0.0:8080->80/tcp old-web

Stop it. A container that’s only stopped doesn’t hold its port:

Terminal window
docker stop old-web
docker rm old-web

2. Docker Compose

Another project might be using the port, since each folder is its own project by default:

Terminal window
docker compose ls
docker ps --format 'table {{.Names}}\t{{.Ports}}\t{{.Label "com.docker.compose.project"}}'

Bring it down from its folder, or by name:

Terminal window
docker compose -p other-project down

The terminal has this situation ready: find the project that holds 8080, bring it down by name, then start yours.

Two services in one file can’t publish the same host port, either. To run several copies of a project, make the port a variable:

services:
web:
ports:
- "${WEB_PORT:-8080}:80"

docker compose up --scale web=2 fails the same way with a fixed port, as both copies ask for it.

Use the Docker Compose Generator to get the file. It only publishes what you ask for.

3. Another program

Terminal window
sudo ss -tlnp | grep ':8080 '
sudo lsof -i :8080 -sTCP:LISTEN

If the last column of ss says docker-proxy, that’s a container, so go back to section 1. Anything else is a program on the host, such as a local web server or a development server you left running. To find what it is, and stop it for good, see address already in use. The Port Lookup tells you what normally runs on a port.

On a Mac:

Terminal window
sudo lsof -nP -iTCP:8080 -sTCP:LISTEN

macOS itself holds port 5000 and 7000, for AirPlay Receiver. Turn it off in System Settings → General → AirDrop & Handoff, or use another port.

4. Nothing’s using it

docker ps and ss show nothing, and the error stays. The daemon may be holding on to it after a crash, or from a container that exited badly. Restart Docker:

Terminal window
sudo systemctl restart docker

On Docker Desktop, use Restart from its menu. Note that restarting stops containers too, except those set up to come back.

5. Windows: excluded port ranges

The “forbidden by its access permissions” message usually means Windows has reserved that port for itself, and no program is using it at all. So your Get-NetTCPConnection shows nothing. See the reserved ranges:

Terminal window
netsh interface ipv4 show excludedportrange protocol=tcp
Start Port End Port
---------- --------
7913 8012
8013 8112

Hyper-V and WSL reserve ranges like these at boot, and they can change on each restart. So 8080 may work today, and not tomorrow. You’ve got a few options:

Choose a port that’s outside the ranges. That’s the simple answer.

Reset them, in an administrator PowerShell. This frees them until the next reservation:

Terminal window
net stop winnat
net start winnat

Reserve your port permanently, so that Windows leaves it alone. While winnat is stopped:

Terminal window
net stop winnat
netsh int ipv4 add excludedportrange protocol=tcp startport=8080 numberofports=1 store=persistent
net start winnat

Or move Windows’s dynamic range away from common ports:

Terminal window
netsh int ipv4 set dynamic tcp start=49152 num=16384

6. Other Ports-are-not-available messages

The end of the message Means
bind: address already in use Another program holds it: section 3
Only one usage of each socket address… The same thing, on Windows: Get-NetTCPConnection
forbidden by its access permissions A reserved range: section 5
permission denied On Linux, a port below 1024 under rootless Docker

For rootless Docker, use a port above 1024, or allow it with sudo sysctl net.ipv4.ip_unprivileged_port_start=80.

7. Publish on a specific address

A port is held per address. You can run two things on one port, if each one uses its own address:

Terminal window
docker run -p 127.0.0.1:8080:80 nginx
docker run -p 10.0.0.5:8080:80 nginx

And 127.0.0.1 is a good idea anyway, for anything that shouldn’t be public.

Warning

A published port goes around many host firewalls like UFW, as Docker adds its own rules. So -p 5432:5432 on a server with a public address exposes that database to the internet. For local tools and databases, use 127.0.0.1:5432:5432, or don’t publish at all and let containers connect by name.

Shell, we have a problem!

Similar, but different: the same idea for a container’s name is container name is already in use. A port that’s published, and can’t be reached, is another problem: see connecting to localhost from a container. address already in use from a program on the host: see that article. And Cannot connect to the Docker daemon means Docker isn’t running at all: see that article. For the commands around this, see the Docker CLI Cheat Sheet. could not find an available, non-overlapping IPv4 address pool is Docker running out of subnets for networks.

$ ./practice.sh

Practice this in the terminal

Open the Terminal Playground with this article’s scenario loaded. It is safe and runs in your browser.

Open the terminal →

Found this useful? Share it.

Found a mistake? Let us know at contact@ohsudo.com.

Tools

Try it yourself

Articles

Related articles