DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Newsletter
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • A Developer's Guide to Mastering Docker Networking Concepts
  • Docker Multi-Stage Builds: Optimizing Development and Production Workflows
  • Scaling Microservices With Docker and Kubernetes on Production
  • Auto Remediation of GuardDuty Findings for a Compromised ECS Cluster in AWSVPC Network Mode

Trending

  • Production-Grade LLM Regression Testing: Contracts, Evals, and Quality Gates
  • Building High-Performance Time-Series Applications With Java and QuestDB
  • OpenAI Watermarks ChatGPT and Codex: What Changes for EU Users
  • Threat Modeling Context-Aware AI: A STRIDE Walkthrough
  1. DZone
  2. Software Design and Architecture
  3. Containers
  4. When One Docker Swarm Replica Became Unreachable Over an Overlay Network: A Production Case With Traefik

When One Docker Swarm Replica Became Unreachable Over an Overlay Network: A Production Case With Traefik

One Docker Swarm replica became unreachable to Traefik over the overlay network, while the service remained available through its healthy replica.

By 
Denis Tiumentsev user avatar
Denis Tiumentsev
·
Oct. 13, 26 · Analysis
Likes (0)
Comment
Save
Tweet
Share
124 Views

Join the DZone community and get the full member experience.

Join For Free

Context

The incident occurred in the production backend infrastructure of a mobile application. External HTTP traffic was handled by Traefik, deployed on Docker Swarm manager nodes. Traefik ran in swarmMode, used providers.docker, was configured to use the mgp_default network, and had lbswarm disabled so that routing used the required overlay network rather than the Swarm VIP.

Traefik

One of the critical services was mgp_router-app. It was an entry-point service with two replicas deployed to preserve availability if one of them failed.

The service used placement constraints, max replicas per node = 1, and a Traefik health check configured for /actuator/health on port 8080. This meant we relied on external health checking and strictly controlled replica placement across nodes.

Swarm-level load balancing was intentionally disabled. We needed routing control at the Traefik layer, along with the ability to quickly remove unhealthy backends based on their health check status. For this production setup, that provided more flexibility than the built-in Swarm load-balancing logic.

What Happened

The issue was neither a widespread outage nor a failure of the entire service. One replica became unreachable to Traefik over the overlay network: a Traefik instance on one of the manager nodes could not establish a connection to that replica’s backend endpoint. The second replica continued to work normally, so the service as a whole remained available.

For regular traffic, the incident did not affect service availability: Traefik continued routing requests to the healthy replica and removed the unavailable backend from routing. During targeted manual testing of the unhealthy replica’s backend endpoint through Traefik, requests ended in a timeout or HTTP 503.

The container appeared healthy, but only locally. The service responded inside the container, and /actuator/health returned UP. However, other containers and Traefik instances on remote nodes could not establish a connection to that replica through its IP address in mgp_default.

Initial Checks

The container had the same DNS name in both networks. This ruled out name mismatch as an independent cause of the unavailability: the issue occurred specifically at the network-connectivity level to the replica IP in mgp_default.

First, we identified the problematic container and inspected its state:

Shell
 
docker ps --filter "name=mgp_router-app" --q
docker inspect 6bd15b62f891


Next, we checked the networks connected to the container:

Shell
 
docker inspect 6bd15b62f891 --format '{{json .NetworkSettings.Networks}}' | jq

Networks connected to the container

The container was attached to two networks:

  • ingress with IP 10.22.3.137/22;
  • mgp_default with IP 10.29.72.232/13.

We then entered the container and checked whether the application was listening on the expected port:

Shell
 
docker exec -it 6bd15b62f891 bash
ss -tuln

Check whether the application was listening on the expected port

The health endpoint also responded correctly:

Shell
 
curl "http://10.29.72.232:8080/actuator/health"


The expected response was:

Shell
 
{"status":"UP"}


At this point, it was clear that the issue was not the application itself, its startup, or its bind address inside the container. The service was alive, but that alone said nothing about its reachability from outside the container.

Checking Connectivity Between Nodes

The next step was critical: We checked whether another node in the cluster could reach the container using its overlay IP.

Shell
 
docker exec -it 373354916bfc bash
ping 10.22.3.137

Check whether another node in the cluster could reach the container using its overlay IP

This was the IP from the ingress network, and the test confirmed ICMP reachability of the address in that network. That indicated the issue did not look like a complete loss of inter-node connectivity.

The situation was different for the mgp_default IP: pinging it from other nodes failed, even though this overlay network was supposed to provide inter-container communication in Docker Swarm.

This distinction was important. ICMP reachability of the address in ingress remained available, while connectivity to the replica through mgp_default was broken. Therefore, the problem was not the container itself or a complete network failure; it was a specific break in the network path used to reach that replica.

What Docker Logs Showed

The dockerd logs on the affected node provided another useful signal. They contained repeated messages related to Swarm network synchronization:

Shell
 
Jun 02 11:08:42 node-router2 dockerd: time="2025-06-02T11:08:42.462965233Z" level=warning msg="bulk sync to node 091d01df89ae failed: failed to send a TCP message during bulk sync: dial tcp 10.170.0.145:7946: i/o timeout"
Jun 02 11:17:02 node-router2 dockerd: time="2025-06-02T11:17:02.581936915Z" level=error msg="Bulk sync to node 091d01df89ae timed out"


The logs also contained NetworkDB stats entries:

Shell
 
Jun 02 11:07:08 node-router2 dockerd: time="2025-06-02T11:07:08.012509772Z" level=info msg="NetworkDB stats node-router2(2642aeb5172b) - netID:q9athb3moj967oxmb3y8xw4lj leaving:false netPeers:58 entries:13563 Queue qLen:2 netMsg/s:7"


These messages do not prove a specific bug or root cause, but they indicate problems with exchanging network state between nodes. Combined with the endpoint being unreachable through mgp_default, they strengthened the working hypothesis of an overlay-networking issue.

This was an important diagnostic signal: the Docker daemon was running, and the container was started, but the cluster’s network state was not ideal and was likely becoming inconsistent during node-to-node state exchange.

Investigating the Hypotheses

Hypothesis 1: The container itself was the problem.
This hypothesis was not confirmed. A curl request inside the container to http://10.29.72.232:8080/actuator/health returned {"status":"UP"}, and ss -tuln showed that the service was listening on the required port.

Hypothesis 2: The problem was port publishing or binding.
This hypothesis was not confirmed. Even though port 10005 was reachable externally, that did not explain why Traefik could not reach port 8080 over the overlay network. The container worked locally, while the issue occurred on the network path between nodes.

Hypothesis 3: Traefik itself was the problem.
Probably not. Traefik was not the source of the failure; it was the first component that detected that the backend was unavailable from its node.

Hypothesis 4: The Docker Swarm overlay network was the problem.
This became the primary working hypothesis. The replica was reachable from inside its container but was not properly reachable from other nodes through its overlay IP.

Shell
 
curl http://10.29.72.232:8080
nc -vz 10.29.72.232 8080


The curl request worked locally, while nc -vz 10.29.72.232 8080 failed from other nodes. This indicated that traffic was not being routed correctly through the overlay network.

An MTU/VXLAN issue was also considered. This is a plausible class of problems for Docker overlay networks, especially when there is an MTU mismatch or a Path MTU Discovery issue. In this case, however, it remained only a hypothesis rather than a confirmed root cause.

Recovery

We restored the problematic replica by forcing Docker Swarm to recreate the task through a rolling update:

Shell
 
docker service update --force \
  --update-parallelism 1 \
  --update-order start-first \
  --update-delay 30s \
  --detach=true \
  mgp_router-app


--force triggered an update even though neither the image nor the service configuration had changed. Swarm recreated the task for the affected replica and reattached it to mgp_default; after that, Traefik could reach it again over the overlay network.

The rollout parameters were selected to avoid affecting service availability:

  • --update-parallelism 1 – update one replica at a time;
  • --update-order start-first – start the new task before stopping the old one;
  • --update-delay 30s – give the new task time to start and pass its checks.

Restarting Docker on the node and placing the node into drain mode were considered fallback measures, but they were not required to resolve this incident.

Why It Happened

The exact upstream root cause cannot be stated without additional evidence. However, the most well-supported explanation is that a local network-state inconsistency occurred in the Docker Swarm overlay network. As a result, one replica remained operational inside its container, but became unreachable through its overlay IP.

The most plausible explanations include:

  • the overlay network on the node was not fully ready when the container started;
  • an issue in Docker libnetwork;
  • an outdated VXLAN routing table;
  • an iptables issue or a race condition while updating network rules;
  • a node restart without restarting the Docker daemon;
  • an issue with a Swarm endpoint that was not properly advertised or connected.

These situations are particularly unpleasant because Docker continues to consider the container running and its internal health check green, while the network path to the replica is already partially broken.

Key Takeaways

The main conclusion is simple: a healthy container does not necessarily mean a reachable replica.

This is critical in production because:

  • a local curl inside the container does not prove external reachability;
  • an internal health check does not guarantee that Traefik can reach the backend;
  • Swarm may remain formally healthy even when one replica has dropped out of normal network connectivity.

Therefore, in such clusters, it is necessary to check not only container state but also inter-node reachability over the overlay network.

What to Monitor

To prevent similar incidents, it is useful to monitor not only service health but also the cluster’s network plane.

The minimum set of checks includes:

  • reachability of container overlay IPs from other nodes;
  • health checks through Traefik;
  • bulk sync and NetworkDB errors in Docker logs;
  • recurring issues on the same node;
  • consistency between a container’s local health and its external reachability.

It is also useful to have a script that specifically checks connectivity between nodes through the overlay network, not just through ingress or localhost.

Conclusion

This case demonstrated several important points.

First, a container can be healthy locally while remaining unreachable externally.
This is especially important for services that handle user traffic.

Second, Traefik is a good early indicator of network problems.
It can reveal that a backend on one node has stopped responding.

Third, Docker Swarm overlay networking can degrade locally.
In that case, the cluster may appear operational, while one replica has already dropped out of normal routing.

Fourth, such incidents must be diagnosed along the network path, not only through application state.
First, check the container from the inside, then verify reachability from other nodes, then inspect Docker logs, and only after that draw conclusions about the root cause.

Docker (software) Network Production (computer science)

Opinions expressed by DZone contributors are their own.

Related

  • A Developer's Guide to Mastering Docker Networking Concepts
  • Docker Multi-Stage Builds: Optimizing Development and Production Workflows
  • Scaling Microservices With Docker and Kubernetes on Production
  • Auto Remediation of GuardDuty Findings for a Compromised ECS Cluster in AWSVPC Network Mode

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook