TL;DR
Docker won't create the network because the subnet you specified โ or the one Docker auto-picked โ collides with something already in use. That something could be another Docker network, a VPN tunnel, or your corporate LAN. The fix: list what's already taken, find a free CIDR block, and create your network with that block pinned explicitly.
# List all existing Docker networks and their subnets
docker network ls
docker network inspect $(docker network ls -q) \
--format '{{.Name}} {{range .IPAM.Config}}{{.Subnet}}{{end}}'
# Create network with a non-overlapping subnet
docker network create --subnet=172.30.0.0/16 my_network
Why This Happens
Docker pulls subnets from RFC 1918 private ranges โ starting at 172.17.0.0/16, then 172.18.0.0/16, 172.19.0.0/16, and so on. The problem is that Docker isn't the only one drawing from that pool.
The error fires when the target subnet is already claimed by:
- An existing Docker network (even one nobody is actively using),
- A VPN interface on the host,
- A corporate LAN that routes through the machine,
- Another container runtime like Podman or a Kubernetes CNI plugin.
Docker's default pool is 172.16.0.0/12 โ that's 172.16.x.x through 172.31.x.x. On a machine that's been running containers for months, the whole range can fill up. At that point, every docker network create without an explicit subnet will fail.
Step 1 โ Find What's Already Taken
This one-liner prints every Docker network alongside its subnet:
docker network inspect $(docker network ls -q) \
--format '{{.Name}} {{range .IPAM.Config}}{{.Subnet}}{{end}}'
Example output on a busy dev machine:
bridge 172.17.0.0/16
host
none
my_app_net 172.18.0.0/16
staging_net 172.19.0.0/24
old_project 172.20.0.0/16
Also check the host's network interfaces. VPN clients quietly grab a 10.x.x.x or 192.168.x.x block the moment you connect:
ip addr show # Linux
ifconfig # macOS
Step 2 โ Pick a Free Subnet
Scan the output and look for gaps. When the 172.x range is packed, jump to a different RFC 1918 class entirely:
10.10.0.0/24โ fits 254 containers, easy to remember10.20.0.0/24โ good second choice if 10.10 is taken192.168.100.0/24โ useful when both 10.x and 172.x are crowded
Not sure if two ranges overlap? Paste your existing subnets into the Subnet Calculator on ToolCraft โ it highlights free blocks visually and runs entirely in the browser, no data uploaded.
Step 3 โ Create the Network With an Explicit Subnet
Pin the subnet at creation time so Docker can't guess wrong:
docker network create \
--driver bridge \
--subnet=10.10.0.0/24 \
--gateway=10.10.0.1 \
my_network
Using Docker Compose? Set it directly in docker-compose.yml:
networks:
my_network:
driver: bridge
ipam:
config:
- subnet: 10.10.0.0/24
gateway: 10.10.0.1
Step 4 โ Remove Stale Networks (Optional but Recommended)
Networks from old projects don't disappear on their own. Ten months of docker-compose up and docker-compose down can leave dozens of orphaned networks behind, each holding a subnet slice.
# Remove all networks not attached to any container
docker network prune
# Remove one specific network by name
docker network rm old_project
After pruning, try creating your network again without specifying a subnet. Docker often finds a free block automatically once the clutter is cleared.
Verify the Fix
# Confirm the network exists with the correct subnet
docker network inspect my_network \
--format '{{range .IPAM.Config}}Subnet: {{.Subnet}} Gateway: {{.Gateway}}{{end}}'
# Spin up a container on the new network and check its IP
docker run --rm --network my_network alpine ip addr show eth0
The container should show an IP in your chosen range โ something like 10.10.0.2/24. If it starts without errors, you're done.
Configuring the Default Address Pool
If you keep hitting this error across multiple projects, the real fix is upstream: tell Docker to stop drawing from 172.x by default. Edit (or create) /etc/docker/daemon.json:
{
"default-address-pools": [
{"base": "10.10.0.0/16", "size": 24}
]
}
Then restart the daemon:
sudo systemctl restart docker
Every new auto-created network will now carve a /24 from 10.10.0.0/16. That's 256 possible networks before you run out โ plenty of room. The crowded 172.x pool stays untouched.
VPN Conflicts
Corporate VPNs are a common culprit. The VPN tunnel claims a block โ say 10.0.0.0/8 or 172.16.0.0/12 โ the moment you connect, and Docker has no way to know. Your only move is to steer Docker away from those ranges entirely.
Pick something the VPN doesn't touch, like 192.168.200.0/24, and lock it in via daemon.json as shown above. If you're unsure which ranges the VPN owns, run ip route while connected โ the VPN routes show up clearly alongside their interface names (usually tun0 or utun).

