BlueByte
network not foundFixed

Docker Compose: network not found

By Haneul SeoUpdated September 8, 20264 min

Hi, it's BlueByte. You run docker compose up on a project that worked yesterday and it stops with a network-not-found error — either network <name> declared as external, but could not be found, or Error response from daemon: network <hash> not found as it tries to start a container. Your compose file didn't change; a network your containers expect isn't there anymore. We'll walk through both message forms, how Compose names and creates its networks, why one goes missing, how to see what's actually there, and how to fix each case.

The two "network not found" messages Compose prints

Two distinct situations produce this. The first is a missing external network:

network shared_net declared as external, but could not be found

Your compose file marks a network external: true, which tells Compose to attach to a network it does not manage — and that network doesn't exist yet. The second is a dangling network reference:

Error response from daemon: network 7b2a...f31 not found

Here Compose, or a container it created earlier, still refers to a network by ID that has since been deleted. You'll hit this on docker compose up, down, start, or restart — the stored reference points at a network the daemon no longer has.

How Compose names and creates its default network

When you run docker compose up, Compose creates a network named <project>_default and attaches every service to it. The project name comes from the directory holding the compose file, unless you override it:

docker compose -p myproj up -d       # or set COMPOSE_PROJECT_NAME=myproj
[+] Running 2/2
 ✔ Network myproj_default   Created
 ✔ Container myproj-web-1   Started

So myapp_default belongs to the myapp project. If you rename the directory or change the project name, Compose starts looking for a differently named network — a common reason a network seems to "vanish" when nothing was actually deleted.

Why the network went missing

The reference breaks for a few concrete reasons:

  • Someone ran docker network prune or docker network rm, removing a network that stopped containers still point to.
  • The Docker daemon or host restarted and a network wasn't recreated the way the old container metadata expects.
  • The compose file declares an external: true network that was never created, or was created under a different name.
  • The project name changed — a renamed directory or an added -p — so Compose now looks for newname_default while the containers live on oldname_default.

See what networks exist and what your project expects

List what the daemon actually has, then confirm what your compose file asks for:

docker network ls
docker compose config --networks

docker network ls shows every network by name and ID; docker compose config --networks prints the networks your merged compose file expects. If a name in the second list isn't in the first, that's your gap. To see which network a stuck container is pinned to:

docker inspect -f '{{json .NetworkSettings.Networks}}' myproj-web-1

Fix the dangling network: bring it down, then recreate

For the dangling-reference case, tear the project down and let Compose rebuild the network. --remove-orphans also clears containers left over from a previous project name:

docker compose down --remove-orphans
docker compose up -d

If down itself fails with the same network error, force the containers to be recreated so they re-attach to a fresh network:

docker compose up -d --force-recreate
 ✔ Network myproj_default   Created
 ✔ Container myproj-web-1   Recreated

Fix a missing external network: create it first

An external: true network must exist before docker compose up. Create it once, then bring the project up:

docker network create shared_net
docker compose up -d

The name has to match exactly. If your compose file gives the network a custom name:, create that name, not the key:

networks:
  shared_net:
    external: true
    name: company_shared

Here you must run docker network create company_shared — Compose looks up company_shared, and shared_net is only the local alias.

A real case: a pruned network after a host reboot

A small stack had been up for weeks. After a host reboot I ran docker system prune to reclaim space, which removed the stopped project's network. docker compose up -d then failed with network 7b2a...f31 not found. docker network ls confirmed myproj_default was gone. docker compose down --remove-orphans cleared the stale references, docker compose up -d recreated myproj_default and re-attached both containers, and the stack was back — no compose file edits, just resetting the project's networking to a clean state.

How it differs from "network already exists" and "port is already allocated"

network not found is the absence case — Compose expects a network that isn't there. network <name> ... already exists is the opposite: a leftover network with the same name blocks creation, cleared with docker network rm. Bind for 0.0.0.0:8080 failed: port is already allocated has nothing to do with networks — a published host port is held by another process. Reading which of the three you got tells you whether to create a network, remove one, or free a port.

Related questions

What's the difference between the external error and the daemon error?

The external error means your compose file expects a network you have to create yourself. The daemon 'network <id> not found' means a container holds a dangling reference to a network that was deleted — fixed by bringing the project down and recreating it.

Will docker compose down --remove-orphans delete my data?

No. It removes containers and the project's default network, not named volumes. Your volumes and images stay. Add -v only if you explicitly want the named volumes gone too.

docker network prune keeps breaking my stacks.

prune removes networks with no running containers attached, so a stopped stack's network is fair game. Run it while the stack is up, or avoid it on hosts running Compose projects, then bring the project back with docker compose up.

My network is external and it exists, but Compose still can't find it.

Check the literal name. When you set name: under an external network, Compose looks up that value, not the key. docker network ls must show that exact name.

Do I have to recreate containers every time?

No — only when the reference is dangling. A normal docker compose restart reuses the existing <project>_default network without recreating anything.

References

Haneul Seo

Infrastructure engineer · 10+ years running Linux fleets

More in this category

detected dubious ownershipFixed

Git: fatal: detected dubious ownership in repository

Since the CVE-2022-24765 fix in Git 2.35.2, Git refuses to read a repository whose working tree or .git directory is owned by a different user than the one running the command. It shows up in containers, CI jobs, sudo sessions and shared drives. Fix the ownership if the repo should be yours, or add the exact path to safe.directory in your global config — never in the repo's own config, which Git ignores for this.

Git
failed calling webhookFixed

Kubernetes: Internal error occurred: failed calling webhook

An admission webhook sits in front of your write, the API server could not get an answer out of it, and failurePolicy: Fail turned that silence into a rejection. The tail of the message is the whole diagnosis: context deadline exceeded means the call went nowhere, no endpoints available means nothing is running, and an x509 line means the API server does not trust the webhook's certificate. Each has a different fix, and none of them is your manifest.

Kubernetes
1205Fixed

MySQL: ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

A statement waited the full innodb_lock_wait_timeout for a row lock another transaction is still holding, and gave up. sys.innodb_lock_waits names the blocking session and hands you the KILL statement, and a blocking_query of NULL means the blocker is idle on an open transaction. The detail most retry loops get wrong: by default only the timed-out statement is rolled back, so your transaction is still open and still holds every lock it took earlier.

MySQL
MISCONFFixed

Redis: MISCONF Redis is configured to save RDB snapshots, but it's currently unable to persist to disk

Reads keep working and every write is rejected, because the last background save failed and stop-writes-on-bgsave-error defaults to yes. The log names the real cause — no space, a dir the redis user can't write, a read-only mount at rename time, or fork failing with Cannot allocate memory. Fix the cause, run one BGSAVE, and writes come back on their own with no restart: rdb_last_bgsave_status flips from err to ok. Setting stop-writes-on-bgsave-error no restores writes instantly but leaves the snapshot broken, so treat it as a deliberate trade, not the fix.

Redis
FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memoryFixed

Node.js: FATAL ERROR: Reached heap limit — JavaScript heap out of memory (exit 134)

The V8 heap has its own ceiling, derived from system memory and the Node release, and it is often far below the RAM you have; when a build or server reaches it, V8 aborts with FATAL ERROR: Reached heap limit and exit code 134. Read the real limit with v8.getHeapStatistics().heap_size_limit, then raise it with --max-old-space-size (in MiB) or NODE_OPTIONS for a large workload, size it below the cgroup limit inside containers, and use --heapsnapshot-near-heap-limit to catch a leak in a long-running process. Exit 137 with no FATAL ERROR line is a container kill, not this.

Node.js
exec /docker-entrypoint.sh: exec format errorFixed

Docker: "exec format error" when the container starts — wrong-platform image, no emulator, or a script with no shebang

The container exits on its first instruction with exec format error — the kernel's ENOEXEC, meaning the file exists but cannot be executed here. In practice that is an image built on one CPU architecture (an Apple-silicon Mac produces linux/arm64) and run on another (an x86_64 server) with no QEMU handler registered in binfmt_misc, or an entrypoint script whose first line is not a shebang. uname -m, docker image inspect and ls /proc/sys/fs/binfmt_misc tell the causes apart; the fix is an explicit docker buildx build --platform (or a manifest list for both), QEMU registration or --platform when you mean to emulate, and a #!/bin/sh line for the script.

Docker