skip to content

What does `docker network inspect` tell you when a container cannot reach the rest of its network?

level: seniorimportance: should knowfreq 46%

answer

  1. Check membership before chasing reachability
  2. One command shows the network's real contents
  3. The Containers map lists running endpoints only
  4. Compare Gateway with the container's default route
  5. Internal true means no outbound path

basics

~20 s

It answers attachment and addressing: the Containers map lists the running containers on that network on this host with their IPv4 addresses, IPAM.Config gives the subnet and gateway, and Internal reveals a network with no outside route. A missing container is the finding.

solid answer

~40 s

It is the fastest way to stop guessing about reachability and check membership first. The `Containers` map keys every attached endpoint by container ID with its `Name` and `IPv4Address` — but only for **running** containers and only on **this host**, so a missing entry usually means the container joined a different network rather than that the data is wrong. `IPAM.Config` gives the subnet and gateway to compare against the container's own `ip route`. `Internal: true` explains a container that reaches its peers but nothing external. `Options` carries per-network settings such as the driver MTU, and `Labels` names the Compose project that owns the network — useful when two checkouts produce similarly named networks. Pair it with `docker inspect -f '{{json .NetworkSettings.Networks}}' <name>` for the container's own view, including its aliases.

code

bash · 4 lines
bash
docker network inspect -f '{{range .Containers}}{{.Name}} {{.IPv4Address}}{{"\n"}}{{end}}' pipeline_default
# thumbs-index 172.29.0.7/16
docker network inspect -f '{{(index .IPAM.Config 0).Subnet}} {{(index .IPAM.Config 0).Gateway}}' pipeline_default
# 172.29.0.0/16 172.29.0.1

go deeper

for a junior

Know that this command answers "which containers are on this network and at what addresses", and that a container missing from the Containers map almost always means it joined a different network than you assumed.

for a middle

Explain the fields you read and why: IPAM.Config for subnet and gateway, Containers for live endpoints, Internal for a network with no outbound route. Know the container-side counterpart, docker inspect on .NetworkSettings.Networks.

for a senior

Show that you check attachment before reachability, and that you know the map's limits — running containers, this host only. Be ready to recognise the stale-endpoint failure and clear it with a forced disconnect rather than a daemon restart.

for a principal

Own why these incidents recur: network names are derived from project directories, ad-hoc docker run bypasses the project network, and nothing warns you. Argue for conventions — explicit project names, declared external networks, and a first-response checklist — rather than better debugging skills.

## What the command answers `docker network inspect <network>` prints one JSON object describing what the network is and what is currently attached to it on this host. During an incident it answers the two questions that come before every other question: - *is the container actually on this network*, - and *what addressing does this network hand out*. ## Reading the output Reading it field by field: - **`Name` / `Id` / `Driver` / `Scope`** — the identity. The name matters more than people expect: Compose creates networks named `<project>_<network>`, and the project name defaults to the directory name. Two checkouts of the same repo in differently named directories produce `thumbs_default` and `pipeline_default`, and a container in one cannot see a container in the other even though both look "default" in a `ps` listing. - **`IPAM.Config`** — an array of `{Subnet, Gateway}` entries, for example `172.29.0.0/16` with gateway `172.29.0.1`. This is what the container's default route should point at. If the container's `ip route` shows a gateway from a different subnet, it is attached somewhere other than where you are looking. - **`Containers`** — a map keyed by container ID, each entry carrying `Name`, `EndpointID`, `MacAddress` and `IPv4Address` (with its prefix, e.g. `172.29.0.7/16`). Three properties of this map trip people up. - It lists only endpoints on **this host**. - It lists only containers that are currently **running** — a stopped container that is still configured for the network vanishes from the map and reappears when it starts. - And it is the definitive answer to "is it attached?", where the container-side view comes from `docker inspect -f '{{json .NetworkSettings.Networks}}' <name>`, which also shows the aliases that container answers to. - **`Internal`** — when `true`, the network deliberately has no route to the outside world. Containers on it reach each other and nothing else. A container that resolves and reaches its peers but cannot reach any external host has usually been placed on an internal network on purpose, and the "fix" is an architectural decision, not a bug. - **`Options`** — driver options, notably `com.docker.network.driver.mtu` and the inter-container-communication switch. A per-network MTU smaller than the interface it rides on is worth noticing when small requests succeed and larger payloads stall. - **`EnableIPv6`, `Attachable`, `Ingress`, `Labels`** — mostly context, but `Labels` carries the Compose project and network names, which is how you prove which project owns a mystery network. ## A worked example A photo-thumbnail pipeline reports that its Java batch job on a distroless base cannot reach `thumbs-index`. 1. `docker network inspect pipeline_default` shows the subnet `172.29.0.0/16`, gateway `172.29.0.1`, and a `Containers` map with exactly one entry: `thumbs-index` at `172.29.0.7/16`. The worker is not in the map at all. 2. `docker inspect -f '{{json .NetworkSettings.Networks}}' thumbs-worker` shows a single key, `bridge` — it was started with a plain `docker run` and never joined the project network. Because the image is distroless there was never any prospect of proving that from inside the container; the whole diagnosis is host-side JSON. The follow-on detail is that the worker's roughly 6-second JVM cold start had made the failure look intermittent to the team, since a retry loop sometimes produced a different error first. ## Two operational habits 1. First, prefer `docker network inspect -f '{{range .Containers}}{{.Name}} {{.IPv4Address}}{{"\n"}}{{end}}' <net>` over reading raw JSON in an incident; a two-column list of who-is-on-this-network-and-at-what-address is what you actually need, and it fits in a terminal. 2. Second, know the **stale-endpoint case**. After an unclean daemon stop, reconnecting a container can fail with `endpoint with name <name> already exists in network <net>` while `docker network inspect` shows no such container — the endpoint record outlived the container. `docker network disconnect -f <net> <name>` removes the orphaned endpoint and lets the container reattach. Reaching for `docker network prune` instead accomplishes nothing here: it removes unused networks, and this network is very much in use. ## What this command cannot tell you It is a description of configuration and attachment, not of reachability. It will not tell you: - whether the peer process is listening, - whether a filter is dropping packets, - or whether the name the client used is the name the peer answers to. Those come from the connect-and-read-the-error rungs; `network inspect` is what stops you from spending an hour on them while the container sits on the wrong network.

  • A container you know is configured for the network does not appear in the `Containers` map. What are the explanations?
    Most often it is genuinely attached elsewhere — started with a plain `docker run` onto the default bridge, or joined a similarly named network from another Compose project. Two benign explanations remain: the container is not running, since the map lists live endpoints only, and it is running on a different host, since the map is host-local. Confirm with `docker inspect -f '{{json .NetworkSettings.Networks}}' <name>`.
  • Reattaching a container fails with "endpoint with name X already exists in network Y", yet inspect shows no such container. How do you clear it?
    An endpoint record outlived its container, typically after an unclean daemon stop. `docker network disconnect -f <network> <name>` removes the orphaned endpoint and lets the container reattach. `docker network prune` does not help — it only removes networks with no attachments, and this one is in use. Restarting the daemon also clears it but disrupts every other container on the host.
  • What can `docker network inspect` never tell you?
    Anything about reachability. It describes configuration and attachment, not whether packets flow: it cannot say whether the peer process is listening, whether the name the client used matches an alias the peer answers to, or whether something is dropping traffic. Those come from resolving the name and connecting to the address. Its value is ruling out the cheap structural cause before you spend an hour on the expensive ones.

saying these in an interview costs you the question

  • Reads it as proof that two containers can reach each other
  • Expects stopped containers to appear in the Containers map
  • Assumes the map covers containers on other hosts
  • Ignores Compose's project prefix on network names
  • Reaches for network prune to clear a stale endpoint
  • Never compares the gateway with the container's default route

context