Skip to content

Fix: Docker error: network has active endpoints

FixDevs · (Updated: )

Part of:  Docker, DevOps & Infrastructure

Quick Answer

How to fix Docker 'network has active endpoints' error when removing networks, caused by running containers, stale endpoints, orphaned compose networks, and failed cleanups.

The Error

You try to remove a Docker network and get:

Error response from daemon: error while removing network: network my-network id abc123def456
has active endpoints

Or:

error: failed to remove network: network my-network has active endpoints

Or during docker-compose down:

ERROR: error while removing network: network my-project_default has active endpoints

Docker refuses to remove the network because one or more containers are still connected to it. Docker networks cannot be deleted while any container — running or stopped — is attached.

Why This Happens

Docker networks are reference-counted. Every container connected to a network holds a reference. When you try to delete the network, Docker checks for active endpoints (container connections). If any exist, the deletion fails.

Under the hood, an endpoint is the network’s view of a connected container: an entry in the network’s Containers map, with an associated IP address, MAC address, and an endpoint_id recorded in Docker’s libnetwork store. The endpoint is created when the container starts and is supposed to be removed when the container stops. The “has active endpoints” error happens when at least one of these entries still exists, even if the container behind it has already been killed or removed from docker ps -a.

Common causes:

  • Containers are still running. You forgot to stop containers before removing the network.
  • Stopped containers still attached. Stopped containers maintain their network attachment until they are removed.
  • Orphaned endpoints. A container was forcefully killed or Docker crashed, leaving stale network endpoints.
  • Docker Compose stale state. A previous docker-compose up created the network, but the compose file changed and docker-compose down cannot clean up properly.
  • Multi-compose projects sharing a network. Multiple Compose projects share an external network, and one project’s containers are still attached.

The reason cleanup is so brittle is that endpoint deletion is a two-step operation: disconnect the container from the network, then remove the endpoint record from libnetwork. If the daemon crashes between those steps, or if a container is force-killed with SIGKILL (no shutdown hooks run), step two is skipped and the endpoint becomes a ghost. The container no longer exists but its endpoint does, and the network refuses to be deleted until you tell Docker to forget that endpoint explicitly.

In Production: Incident Lens

This error is almost always a cleanup-during-deploy incident, not a runtime failure. The typical pattern: CI tears down the previous stack with docker-compose down, the orchestrator races a container shutdown against the network removal, the container has not finished its graceful stop window, and the network removal aborts. The deploy script either retries forever or fails the pipeline, depending on how it is written.

Blast radius is “deploy is stuck” — the running stack keeps serving traffic, but the new version cannot replace it because the old network refuses to leave. On a single-host setup that is annoying. On a CI host shared between many projects, one stuck network can wedge subsequent jobs that try to reuse the same network name, and you end up with a pile-up of failed pipelines all reporting the same error. The monitoring signal is a deploy job that hangs past its normal wall-clock duration, or repeated docker network rm retries in the deploy log.

Recovery in production is almost always force-disconnect every endpoint with docker network disconnect -f, remove the network, then re-run the deploy. The postmortem preventive has two parts. First, make container shutdown actually graceful: set stop_grace_period in compose, ensure your process handles SIGTERM cleanly, and stop accepting new connections before exit. Second, sequence docker-compose down correctly — stop services in dependency order, wait for actual exit, then remove the network as a separate step. A flat docker-compose down --remove-orphans -t 30 -v is far more reliable than a one-line down that races.

Fix 1: Find and Stop Connected Containers

Identify which containers are using the network:

docker network inspect my-network --format '{{range .Containers}}{{.Name}} {{end}}'

Or for detailed information:

docker network inspect my-network

Look at the Containers section in the JSON output. It lists every container connected to the network.

Stop and remove the containers:

docker stop container1 container2
docker rm container1 container2

Then remove the network:

docker network rm my-network

Pro Tip: Use docker network inspect with jq for cleaner output:

docker network inspect my-network | jq '.[0].Containers | keys[]'

This lists only the container IDs, which you can pipe to docker stop and docker rm.

Fix 2: Disconnect Containers from the Network

If you do not want to stop the containers but just want to free the network, disconnect them first:

docker network disconnect my-network container1
docker network disconnect my-network container2

Then remove the network:

docker network rm my-network

Force disconnect if a normal disconnect fails (e.g., the container no longer exists):

docker network disconnect -f my-network container1

The -f flag forces disconnection even if the container is not running or has been removed.

Fix 3: Fix Stale Endpoints

Sometimes Docker reports active endpoints even though no containers are visibly connected. This happens after crashes, forced kills, or Docker daemon restarts.

Check for ghost containers:

docker network inspect my-network

If the Containers section lists containers that docker ps -a does not show, you have stale endpoints.

Fix: Force disconnect the stale endpoint:

docker network disconnect -f my-network <container-id-from-inspect>

Use the container ID shown in the network inspect output, even if the container no longer exists.

Fix: Restart the Docker daemon:

sudo systemctl restart docker

A daemon restart cleans up stale network state. Warning: This stops all running containers briefly. They restart if they have a restart policy.

If the Docker daemon itself is not running, see Fix: Docker daemon is not running.

Fix 4: Fix Docker Compose Network Issues

Docker Compose creates a default network named <project>_default for each project. Common issues:

Orphaned containers from a previous run:

docker-compose down --remove-orphans

The --remove-orphans flag removes containers from services that are no longer defined in the compose file.

If docker-compose down itself fails:

# Stop all containers in the project
docker-compose stop

# Remove containers
docker-compose rm -f

# Now remove the network manually
docker network rm my-project_default

If the compose file was renamed or moved:

Docker Compose uses the directory name as the project name. If you moved the compose file, the project name changed and docker-compose down cannot find the old containers.

# Specify the old project name explicitly
docker-compose -p old-project-name down

Common Mistake: Running docker-compose down from a different directory than where you ran docker-compose up. The project name is derived from the directory name, so down looks for containers under the wrong project name and cannot find or stop them.

Fix 5: Handle External Shared Networks

When multiple Compose projects share an external network, you cannot remove it until all projects disconnect:

# compose-project-a.yml
networks:
  shared:
    external: true
    name: my-shared-network
# compose-project-b.yml
networks:
  shared:
    external: true
    name: my-shared-network

Find all containers on the shared network:

docker network inspect my-shared-network --format '{{range .Containers}}{{.Name}} ({{.IPv4Address}}){{"\n"}}{{end}}'

Stop all projects using the network:

cd project-a && docker-compose down
cd project-b && docker-compose down

Then remove the network:

docker network rm my-shared-network

Fix 6: Prune Unused Networks

If you have many unused networks and want to clean them all up:

docker network prune

This removes all networks not used by at least one container. Docker asks for confirmation first.

Skip the confirmation prompt:

docker network prune -f

Prune networks older than a certain age:

docker network prune --filter "until=24h"

This removes networks created more than 24 hours ago that are not in use.

Full system cleanup (networks, containers, images, volumes):

docker system prune -a

Warning: docker system prune -a removes everything not currently in use — all stopped containers, all unused images, all unused networks, and all build cache. It does not remove volumes unless you add --volumes. Use with caution. For disk space issues, see Fix: Docker no space left on device.

Fix 7: Fix Network Issues After Docker Upgrade

After upgrading Docker, the network subsystem might have stale state from the old version:

# Check for inconsistencies
docker network ls
docker network inspect bridge

# Restart Docker to reinitialize networking
sudo systemctl restart docker

If specific networks are corrupted, remove and recreate them:

docker network rm my-network
docker network create my-network

For custom networks with specific subnets:

docker network create --subnet=172.20.0.0/16 --gateway=172.20.0.1 my-network

Fix 8: Handle Swarm Mode Networks

In Docker Swarm mode, networks behave differently. Service networks cannot be removed while services use them:

# Check which services use the network
docker service ls --filter "network=my-overlay-network"

# Remove the services first
docker service rm my-service

# Then remove the network
docker network rm my-overlay-network

Force remove a stuck Swarm network:

docker network rm my-overlay-network

If this fails, leave and rejoin the swarm:

docker swarm leave --force
docker swarm init

Warning: Leaving the swarm stops all services and removes all swarm state. Only do this as a last resort.

If Docker containers are having port conflicts instead of network issues, see Fix: Docker port is already allocated.

Still Not Working?

If the network still reports active endpoints after trying all fixes:

Check for containers in other namespaces. Docker Desktop on macOS/Windows uses a VM. Containers might be running inside the VM that are not visible from docker ps:

docker ps -a --format "{{.ID}} {{.Names}} {{.Status}}" | grep -i exit

Check for Kubernetes-managed containers. If Docker Desktop has Kubernetes enabled, Kubernetes creates its own networks and containers. These might hold references to your networks:

docker ps -a | grep k8s

Do not remove Kubernetes-managed containers or networks manually.

Check for Docker daemon bugs. Some Docker versions have bugs where network endpoints are not cleaned up properly. Update Docker:

sudo apt update && sudo apt install docker-ce docker-ce-cli containerd.io

Check iptables rules. Docker manages iptables rules for networking. Corrupted rules can interfere with network operations:

sudo iptables -L -n | grep -i docker

Check for containers using the network in another Docker context. If you use docker context to talk to a remote daemon (a Linux VM, a CI runner, a remote dev box), docker ps only shows containers from the current context. A container on a different context can still hold an endpoint on a network whose name collides with yours. Run docker context ls and inspect each context’s container list.

Check for containers held open by docker run --rm that died mid-execution. A --rm container that crashes during startup sometimes leaves an endpoint behind because the cleanup path runs after the network detach step. The container is gone from docker ps -a but the endpoint persists. This is the single most common cause of “ghost endpoints” in CI. Force disconnect by endpoint ID:

docker network inspect my-network | jq '.[0].Containers | keys[]' | xargs -I {} docker network disconnect -f my-network {}

Check for docker-proxy processes still holding the network namespace. On Linux, docker-proxy userland processes proxy published ports. If a docker-proxy process leaks (the container exited but the proxy did not), the network namespace stays referenced. Find leaked proxies:

ps aux | grep docker-proxy | grep -v grep

Kill the orphan proxy, then retry docker network rm. If killing it does not help and you cannot afford a full daemon restart, you may have to fall back to the reset below.

Last resort — reset Docker networking entirely:

sudo systemctl stop docker
sudo rm -rf /var/lib/docker/network
sudo systemctl start docker

This deletes all Docker network state and forces Docker to recreate it from scratch. All custom networks are lost. Only use this if nothing else works.

For containers that exit immediately after starting and leave behind stale endpoints, see Fix: Docker container keeps restarting.

F

FixDevs

Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.

Was this article helpful?

Related Articles