Skip to main content
DevOps Insightsguides & answers

Docker · troubleshooting

Bind for 0.0.0.0:PORT failed: port is already allocated

Something already holds the host port you asked Docker to publish, so the new container cannot bind it. Usually another running container, and sometimes a process on the host that has nothing to do with Docker.

First published

New to this? Read what is actually happening first, then come back to the steps.

On this page · 10 sections

Before you start

  • A terminal on the Docker host, or on the Mac or Windows machine running Docker Desktop, as a user who can run docker commands (root-equivalent on Linux).
  • sudo rights for the host checks in the diagnose steps (ss -tlnp or lsof), so they can show processes that belong to other users.
  • The exact address and port from the error, for example 0.0.0.0:8080, and the docker run command or compose file that asked for it.
  • Your Docker Engine version from docker version, because the wording of the host-process error changed in Docker Engine 28.
  • Agreement from whoever owns the container or process holding the port before you stop it.

Run this first

step 1 of 3
docker ps --format 'table {{.Names}}	{{.Ports}}' | grep -F ':8080'

Look for Any container publishing the same host port.

Checks the obvious case first — another running container.

Work out which cause you have

A few questions to narrow the list. Every answer ends in a command that confirms or rules the cause out — this cannot see your cluster, so nothing here is a certainty until you have checked.

Narrow it down

0 answered · nothing is sent anywhere

Does docker ps show another container publishing that host port?

Cause space

3 of 3 still possible

  • Another container already publishes that host portCommon
  • A process on the host holds the port, unrelated to DockerCommon
  • A scaled compose service is trying to publish the same fixed port more than onceOccasional

Nothing ruled out yet. Answer the question above and the branches your answer eliminates will strike through here.

Check it with a tool

Or diagnose it manually

In this order. The first command usually contains the whole answer.

  1. Step 1

    docker ps --format 'table {{.Names}}	{{.Ports}}' | grep -F ':8080'

    Checks the obvious case first — another running container.

    Look for Any container publishing the same host port.

  2. Step 2

    docker ps -a --format 'table {{.Names}}	{{.Status}}	{{.Ports}}' | grep -F '8080'

    Includes stopped containers to rule them out. Docker releases a container's host ports when it exits and clears its PORTS column, so a cleanly stopped container is not the holder, although Docker Desktop's troubleshooting page still lists a container that was not stopped properly as a possible cause.

    Look for A running container that lists the port. If none does, go to the next step to find the process that holds it.

  3. Step 3

    sudo ss -tlnp | grep ':8080' || sudo lsof -iTCP:8080 -sTCP:LISTEN

    If Docker is not holding it, something on the host is. This is the step people skip.

    Look for A PID that is not dockerd, docker-proxy or, with Docker Desktop, com.docker.backend.

Every cause, and how to fix it

Ordered by how often each one turns out to be the answer.

Another container already publishes that host port

Common

The most common case, and often a previous run of the same stack that was never stopped. Compose projects with different names will happily run side by side and collide on ports.

Confirm

docker ps --format 'table {{.Names}}	{{.Ports}}' | grep -F ':8080'

Any container listing 0.0.0.0:8080-> in its ports.

Fix

  • Stop the container that holds it, or publish this one on a different host port — the container port does not need to change.
  • For a duplicated compose stack, bring the old one down with docker compose down rather than stopping containers individually, so its networks go too (add --remove-orphans to also remove containers for services no longer in the file).
docker run -p 8081:3000 myapp   # host port changed, container port unchanged

Only the left-hand number is contended. The application inside still listens on 3000.

A process on the host holds the port, unrelated to Docker

Common

A local dev server, a database installed directly on the machine, or a system service. Docker reports this as a bind failure (address already in use) rather than port is already allocated, and does not name the process holding the port.

Confirm

sudo ss -tlnp | grep ':8080' || sudo lsof -iTCP:8080 -sTCP:LISTEN

A PID and process name that is not Docker's own listener: dockerd or docker-proxy with Docker Engine on Linux, or com.docker.backend (qemu on Linux) with Docker Desktop. That is your answer, and it is not a Docker problem.

Fix

  • Stop the host process, or pick a different host port for the container.
  • On macOS and Windows this is worth checking early — the Docker VM's port forwarding makes it look like a Docker problem while the conflict is on the host side.

A scaled compose service is trying to publish the same fixed port more than once

Occasional

Scaling a service that publishes a fixed host port means every replica asks for the same port. The first succeeds and the rest fail, which reads as a mysterious partial start-up.

Confirm

docker compose config | grep -A3 'ports:'

A fixed HOST:CONTAINER mapping on a service you are scaling above one replica.

Fix

  • Publish a port range, or let Docker assign the host side by giving only the container port.
  • For anything real, put the replicas behind a proxy rather than exposing each one on its own host port.

Understanding it properly

Skip this if you are mid-incident — the working part of the page is above. Worth reading afterwards, because understanding the mechanism is what stops the next one.

In plain terms

When you publish a container port with -p, Docker asks your machine for a port on the outside, called the host port. Only one program can hold a given host port at a time. This error means something already holds the one you asked for: another container, or an ordinary program on your machine.

The two forms of the error, from Docker's documentation

Documented, not reproduced: Docker is not installed on this machine. Both messages are quoted from Docker Desktop's troubleshooting page, which lists them as alternatives under port already allocated errors. The page does not show the command that produced them; any docker run or docker compose up that publishes host port 8080 can.

Command

docker run -p 8080:<container-port> <image>

Output · as shown in Docker — Troubleshoot topics for Docker Desktop: port already allocated errors

Bind for 0.0.0.0:8080 failed: port is already allocated

listen tcp:0.0.0.0:8080: bind: address is already in use

How to read it

  • port is already allocated comes from Docker's own port allocator: Docker Engine's source formats it as Bind for %s:%d failed: port is already allocated. Another container holds the port, so start with docker ps.
  • The second form is the operating system refusing the bind, which means a process Docker does not know about holds the port. Its wording varies by version and platform: Docker Engine 28 and later say failed to bind host port ...: address already in use. Search for already in use, which every variant contains.
  • 0.0.0.0:8080 is the host address and port Docker tried to bind. Docker uses 0.0.0.0 when your -p option names no address, which means all host interfaces.
  • Docker's page lists this under topics for all platforms, but its suggestions for finding the process are Windows tools: resmon.exe, or netstat -aon | find /i "listening " in PowerShell. On Linux and macOS, use ss or lsof as in the diagnose steps.

Words used on this page

Host port
The port on your machine that -p opens: the left-hand number in -p 8080:3000. This is the only number that can collide.
Container port
The port the application listens on inside its container: the right-hand number. Any number of containers can use the same container port at once.
Publishing
Mapping a host port to a container port with -p or Compose ports. With no host address given, Docker publishes on all host addresses, IPv4 and IPv6.
Port allocator
Docker's own record of which host ports its containers hold. port is already allocated comes from it, so Docker itself has already given that port out, normally to another running container.
docker-proxy and dockerd
Docker Engine's processes on Linux. When ss or lsof shows one of them holding the port, a container has it.
com.docker.backend
The Docker Desktop process that listens on published host ports on Mac and Windows and forwards connections into Docker's VM. On Docker Desktop for Linux the same job is done by qemu.
Dynamic host port
What you get when you publish only the container port, such as -p 3000 or ports: ["3000"]. Docker picks a free host port, and docker port or docker compose port shows which.
What is actually happening

Publishing a port with -p 8080:3000 asks the Docker daemon to bind host port 8080. A host port can have exactly one owner, so if anything already holds it, the bind fails and the container never starts.

The confusing part is who counts as "anything". A running container is the obvious case, and that is what port is already allocated reports. A plain host process (a local development server, a database installed on the machine, a system service) holds it too, and Docker reports that as a bind failure, address already in use, without naming the process. A stopped container holds no host port.

This is a host-level conflict rather than a container problem, which is why looking inside the container tells you nothing.

How to tell this is your problem
WhereWhat you see
docker run / docker compose upError response from daemon: ... Bind for 0.0.0.0:8080 failed: port is already allocated
docker psAnother container listing the same host port in its PORTS column.
docker run / docker compose upaddress already in use, worded failed to bind host port ...: address already in use on Docker Engine 28 and later and wrapped in Error starting userland proxy: on older releases, when the holder is a process outside Docker.
ss -tlnp / lsof -iA non-Docker process listening on the port.

How to know it is actually fixed

  • The container starts and docker ps shows 0.0.0.0:<host>-><container>/tcp with the arrow present.
  • A request to the host port reaches the application rather than being refused.

Stopping it happening again

  • Prefer letting Docker assign host ports for anything you do not need at a fixed address, and look the assignment up when you need it.
  • Use docker compose down rather than stop when finishing with a stack, so its containers and networks are removed and the next up starts clean. Stopping already frees the ports.
  • Keep local host services on ports that your compose files do not use — colliding with your own Postgres install is a recurring waste of an afternoon.

Security considerations

  • A port published without an address, as in -p 8081:3000, listens on all host interfaces, IPv4 and IPv6. Docker's documentation calls publishing "insecure by default" and warns that these ports bypass ufw rules, because Docker routes the traffic before ufw sees it. When you move a container to a new host port, publish it as -p 127.0.0.1:8081:3000 unless other machines need to reach it.
  • Letting Docker pick the host port does not hide it. -p 3000 still publishes on every host address, only on a port you did not choose, so treat a dynamic port as exposed too.
  • On Docker Engine releases older than 28.0.0, Docker's documentation warns that hosts on the same layer 2 network segment can reach ports published to 127.0.0.1. Check docker version before relying on a localhost binding on a shared network.
  • docker compose down keeps your data, but docker compose down -v also removes the named volumes declared in the compose file and anonymous volumes. Leave -v off when all you want is the port back.

Sources

Behaviour described here is drawn from official documentation. Where a figure could not be confirmed on an official page it is attributed in the text rather than stated as canonical.

Terms used here (1)

Short definitions for the vocabulary on this page, in case any of it is new. Each links to the full entry.

Docker Compose
A tool for defining and running multi-container Docker applications using a YAML configuration file. With a single command you can spin up all the services your app needs — databases, caches, workers — in an isolated environment.

All 59 terms in the glossary

Did this get you to an answer?

No text box on purpose — please do not paste production logs anywhere

Something wrong or out of date? Report it