Fix: Docker error: network has active endpoints
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 endpointsOr:
error: failed to remove network: network my-network has active endpointsOr during docker-compose down:
ERROR: error while removing network: network my-project_default has active endpointsDocker 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 upcreated the network, but the compose file changed anddocker-compose downcannot 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-networkLook 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 container2Then remove the network:
docker network rm my-networkPro Tip: Use
docker network inspectwithjqfor cleaner output:docker network inspect my-network | jq '.[0].Containers | keys[]'This lists only the container IDs, which you can pipe to
docker stopanddocker 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 container2Then remove the network:
docker network rm my-networkForce disconnect if a normal disconnect fails (e.g., the container no longer exists):
docker network disconnect -f my-network container1The -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-networkIf 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 dockerA 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-orphansThe --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_defaultIf 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 downCommon Mistake: Running
docker-compose downfrom a different directory than where you randocker-compose up. The project name is derived from the directory name, sodownlooks 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-networkFind 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 downThen remove the network:
docker network rm my-shared-networkFix 6: Prune Unused Networks
If you have many unused networks and want to clean them all up:
docker network pruneThis removes all networks not used by at least one container. Docker asks for confirmation first.
Skip the confirmation prompt:
docker network prune -fPrune 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 -aWarning: 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 dockerIf specific networks are corrupted, remove and recreate them:
docker network rm my-network
docker network create my-networkFor custom networks with specific subnets:
docker network create --subnet=172.20.0.0/16 --gateway=172.20.0.1 my-networkFix 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-networkForce remove a stuck Swarm network:
docker network rm my-overlay-networkIf this fails, leave and rejoin the swarm:
docker swarm leave --force
docker swarm initWarning: 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 exitCheck 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 k8sDo 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.ioCheck iptables rules. Docker manages iptables rules for networking. Corrupted rules can interfere with network operations:
sudo iptables -L -n | grep -i dockerCheck 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 grepKill 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 dockerThis 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.
Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.
Was this article helpful?
Related Articles
Fix: Docker Error: Bind for 0.0.0.0:PORT failed: port is already allocated
How to fix Docker port is already allocated error by finding processes using the port, removing stopped containers, changing port mappings, and resolving Docker Compose port conflicts.
Fix: Fly.io Deploy Not Working — fly.toml, Machines, Volumes, Secrets, and Internal DNS
How to fix Fly.io errors — fly.toml app vs name confusion, machines API vs legacy apps, Dockerfile build failures, volume per-region, secrets staging, fly proxy for local access, and internal IPv6 routing.
Fix: Docker Compose Watch Not Working — sync vs rebuild, Ignore Patterns, WSL/macOS File Events
How to fix docker compose watch errors — develop.watch directive not firing, sync vs sync+restart vs rebuild differences, ignore globs not matching, WSL2 file events delayed, named volumes shadowing watch, and Compose version requirements.
Fix: Coolify Not Working — Deployment Failing, SSL Not Working, or Containers Not Starting
How to fix Coolify self-hosted PaaS issues — server setup, application deployment, Docker and Nixpacks builds, environment variables, SSL certificates, database provisioning, and GitHub integration.