Intro
Docker Secrets give you a built-in way to handle passwords, API keys, certificates, and other sensitive material without baking them into images or environment variables. In Docker Swarm, secrets are encrypted during transit and at rest, and only mounted into containers that are explicitly granted access. The storage side is straightforward. The trouble usually starts when a service tries to reach the secret mount or to talk to another service that depends on those secrets, and a network problem gets in the way.
This guide is a practical walkthrough for those moments. We will cover DNS resolution inside the overlay network, port connectivity between services, routing behavior across nodes, firewall rules that silently block Swarm traffic, and safe diagnostic commands you can run without taking down production. You will leave with a repeatable process: establish a baseline, inspect the configuration, test each layer, isolate the failure, and recover with a rollback plan.
Version and Environment Inventory
Before you change anything, know what you are working with. Version mismatches and node misconfigurations are frequent root causes, and you want to rule them out early.
Verify Docker and Swarm Versions
Run this on a manager node:
docker version --format '{{.Server.Version}}'
Expected output:
20.10.17
Now confirm the node is a manager and the Swarm is healthy:
docker info --format '{{.Swarm.LocalNodeState}} {{.Swarm.ControlAvailable}}'
Expected output:
active true
If the local node state is not active, or control is not available, you are not on a manager node. All docker service and docker network management commands must run on a manager.
List Nodes and Networks
Get a picture of the cluster:
docker node ls
Look for nodes with status Ready and availability Active. A node in Down or Drain state can explain missing service replicas or unreachable containers.
Then list networks:
docker network ls
Pay attention to the driver and scope. Docker Swarm overlay networks use the overlay driver and have swarm scope. A network created with the bridge driver is local to a single node and will not route traffic between containers on different hosts.
Prerequisites for Troubleshooting
- SSH access to at least one manager node and to any worker node where the service is scheduled.
- Permissions to run
dockercommands, usually viasudoor membership in thedockergroup. - A basic mental model of Swarm services, tasks, and overlay networking.
- A test service or stack that reproduces the issue without touching production data.
Safe Configuration Path
When a service cannot reach a secret or another service, the temptation is to remove and recreate the network, or restart the whole stack. Resist that. Scoped, reversible changes let you isolate the problem without collateral damage.
Inspect Service Configuration
First, see how the service is defined:
docker service inspect --pretty <service-name>
Look for the network attachments and the secret mounts. Here is a trimmed example from a real service:
Networks:
frontend-overlay
Secrets:
db_password
Target: /run/secrets/db_password
The secret target path is the file path inside the container. If the application expects the secret at a different location, it will fail even though the secret exists.
Now inspect the network itself:
docker network inspect --verbose <network-name>
This shows the subnet, gateway, and the containers attached to that network. Verify the service's container is listed. If it is not, the service is not on that network, no matter what the service spec says.
Add a Test Service on the Same Network
To test network behavior from inside the overlay, create a temporary service attached to the same network:
docker service create --name test-secret-net --network <network-name> alpine sleep 3600
This creates a single replica of an Alpine container that sleeps for an hour, giving you time to run diagnostics. Get the container ID:
docker ps -q --filter name=test-secret-net
Then exec into it:
docker exec -it $(docker ps -q --filter name=test-secret-net) sh
Inside the container, test secret access if the service under test should have a secret:
cat /run/secrets/my-secret
If the file is missing, the secret is not mounted. That is a configuration issue, not necessarily a network issue, but it often shows up alongside network problems because the service cannot start and thus never joins the network properly.
Isolate DNS Issues
Docker's embedded DNS server runs at 127.0.0.11 inside each container. It resolves service names to virtual IPs (VIPs) on the overlay network. Test resolution inside the test container:
nslookup <service-name>
Expected output includes the VIP:
Name: <service-name>
Address: 10.0.0.2
If resolution fails, check that the service is attached to the same network as the test container. DNS resolution only works for services on the same overlay network. Also verify that the DNS server is reachable:
cat /etc/resolv.conf
It should show nameserver 127.0.0.11. If it shows an external DNS server, something is wrong with the container's network setup.
Verification and Diagnostics
Now work through each layer systematically: DNS, ports, routing, and firewall. Each test either clears a layer or points to the culprit.
DNS Resolution Tests
Inside the test container, use dig or nslookup to query the service name. For a service called my-web on the frontend network:
dig my-web +short
Expected result:
10.0.0.2
If the service is attached to multiple networks, the DNS server returns a VIP per network. Query with the full network-scoped name if needed:
dig my-web.frontend +short
You can also check the service's VIP directly:
docker service inspect my-web --format '{{json .Endpoint.VirtualIPs}}'
This shows the VIP per network, for example:
[{"NetworkID":"abcd1234","Addr":"10.0.0.2/24"}]
If DNS fails, the service may not have any replicas running, or the service is not on the same network.
Port Connectivity
Once DNS works, test whether the TCP port is open. The nc (netcat) command is available in many images, or you can install it in the test container:
apk add --no-cache netcat-openbsd
Then test connectivity:
nc -zv my-web 80
Expected output:
my-web (10.0.0.2:80) open
If the port is closed, check whether the service actually publishes the port. For internal service-to-service communication, the service does not need to publish a port with --publish; it simply needs to listen on the port inside the container. Inspect the service's port configuration:
docker service inspect my-web --format '{{json .Endpoint.Ports}}'
If no ports are listed, the service is not exposing any ports to the outside world, but it may still listen internally. To see what the process inside the container is doing, exec into one of the service's containers:
docker exec <container-id> netstat -tulpn
Look for the expected port in the LISTEN state.
Routing Checks
Basic IP routing can be tested with ping. From the test container:
ping -c 4 my-web
If you get replies, IP routing works. If ping fails, do not immediately assume a routing problem: many production images disable ICMP echo, or firewall rules block ping. Use traceroute to see the path:
traceroute my-web
Inside the overlay network, you should see a direct route to the VIP without any intermediate hops, because the VIP is handled by the local routing mesh.
For a deeper look at the container's network configuration:
ip addr show
ip route
Verify that the default gateway matches the overlay network's gateway. You can get the gateway from docker network inspect:
docker network inspect frontend-overlay --format '{{json .IPAM.Config}}'
Example output:
[{"Subnet":"10.0.0.0/24","Gateway":"10.0.0.1"}]
If the container's default route points elsewhere, the container may have been started with the wrong network configuration.
Firewall Checks
Firewall rules on the Docker hosts frequently block Swarm traffic. Docker manages its own iptables chains, but user-defined rules in the DOCKER-USER chain can override them. On a Linux host, run:
sudo iptables -L DOCKER-USER -n -v
Look for REJECT or DROP rules that might affect ports:
2377/tcpfor cluster management communication7946/tcpand7946/udpfor node communication4789/udpfor overlay network traffic
For example, a rule like this blocks VXLAN traffic:
Chain DOCKER-USER (1 references)
pkts bytes target prot opt in out source destination
0 0 DROP udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpt:4789
If such a rule exists, remove it or adjust it. Also verify that the ports are open between nodes using ss or nc from the host:
sudo ss -lntup | grep -E '2377|7946|4789'
This shows whether the Docker daemon is listening on those ports.
Secret-Specific Diagnostics
If a service fails to start because of a missing secret, inspect the service logs:
docker service logs <service-name>
A common error message:
secret not found: my-secret
This means the service was created with a reference to a secret that does not exist. List the secrets:
docker secret ls
If the secret exists but the container cannot access it, check the service's secret configuration:
docker service inspect <service-name> --format '{{json .Spec.TaskTemplate.ContainerSpec.Secrets}}' | jq .
Example output:
[
{
"File": {
"Name": "/run/secrets/my-secret",
"UID": "0",
"GID": "0",
"Mode": 292
},
"SecretID": "somesecretid",
"SecretName": "my-secret"
}
]
The File.Name is the target path. The Mode is the octal permission, here 292 decimal which is 0444 in octal, meaning readable by all. If the mode is 0, the file may be inaccessible. Also verify the UID and GID match the user running the process in the container.
Inside the container, check the file:
ls -l /run/secrets/
If the file exists but is unreadable, adjust the secret target permissions or run the container as a user with appropriate access.
Failure Modes and Recovery
Recognizing the common failure patterns speeds recovery. For each, we describe the symptom, likely cause, and concrete recovery steps.
DNS Resolution Failure
Symptom: nslookup or dig returns no answer, or the service name cannot be resolved.
Cause: The service and test container are not on the same overlay network, or the service has no running replicas, or the embedded DNS is misconfigured.
Recovery:
- Check the service's networks:
docker service inspect my-service --format '{{json .Spec.TaskTemplate.Networks}}'
- If the network is missing, add it:
docker service update --network-add frontend-overlay my-service
- Ensure at least one replica is running:
docker service ps my-service
- Test resolution again from the test container.
Port Connectivity Failure
Symptom: nc reports connection refused or times out when connecting to the service port.
Cause: The service is not listening on the expected port inside the container, or a firewall rule is blocking the connection, or the service has no running tasks.
Recovery:
- Verify the service is running:
docker service ps my-service
- Check the port the service believes it is exposing:
docker service inspect my-service --format '{{json .Endpoint.Ports}}'
- Inside a running container of the service, check listening ports:
docker exec <container-id> netstat -tulpn | grep <port>
- If no process is listening, fix the application configuration or Dockerfile
EXPOSEdirective. If the port is listening but connection fails, check firewall rules as described earlier.
Secret Access Failure
Symptom: The container cannot read the secret file, or the file is missing.
Cause: The secret is not mounted correctly, the target path is wrong, or the permissions are too restrictive.
Recovery:
- List secrets and confirm the intended secret exists:
docker secret ls
- Recreate the service with the correct secret target if the path is wrong:
docker service update --secret-rm my-secret --secret-add source=my-secret,target=/run/secrets/db_password my-service
- Verify inside a container:
docker exec <container-id> ls -l /run/secrets/
The output should show the file with reasonable permissions, e.g., -r--r--r-- 1 root root.
Network Performance Degradation
Symptom: High latency or packet loss between services on the overlay network.
Cause: Overlay network misconfiguration, MTU issues, or underlying infrastructure problems.
Recovery:
- Test for packet loss:
ping -c 100 <target>
- Check for MTU mismatches. Overlay networks add VXLAN overhead, so the MTU must be lower than the underlying network. Inspect the network's MTU:
docker network inspect frontend-overlay --format '{{json .Options}}'
Look for com.docker.network.driver.mtu. The default is usually 1450. If the underlying network has an MTU of 1500 and the overlay is set to 1500, fragmentation can occur. Set the correct MTU when creating the network:
docker network create -d overlay --opt com.docker.network.driver.mtu=1400 my-overlay
- If problems persist, consider recreating the overlay network and reattaching services. This disrupts traffic, so schedule a maintenance window and use the rollback plan.
Rollback Strategies
Always be able to undo changes. For services, use:
docker service rollback <service-name>
This reverts to the previous service specification, including networks and secrets. Note that only the immediately previous specification is stored.
For network changes, document the original state before any modification:
docker network inspect <network-name> > network-backup.json
If needed, remove the network and recreate it from the backup. However, removing an overlay network disconnects all attached services and may cause brief downtime.
Common Pitfalls and How to Avoid Them
Several mistakes recur in the field. Here are the most frequent and how to prevent or recover from them.
1. Testing from the Wrong Network
Why it happens: It is easy to create a test container on the default bridge network or a different overlay and then try to reach a service by name. Docker's DNS resolution is network-scoped, so the name will not resolve.
How to avoid: Always specify the same overlay network when creating the test service:
docker service create --name test-container --network <service-network> alpine sleep 3600
Double-check with docker inspect that the test container is attached to the intended network.
2. Ignoring Firewall Rules on Hosts
Why it happens: Many administrators focus on the container network and forget that host-level firewalls can block Swarm's inter-node communication. Docker's own iptables rules are usually permissive, but user-added rules in the DOCKER-USER chain can override.
How to avoid: Always check iptables -L DOCKER-USER -n -v on both source and target hosts during troubleshooting. Explicitly allow ports 2377, 7946, and 4789 if you have a restrictive firewall policy.
3. Overlooking Secret Target Paths
Why it happens: The secret name and the file path inside the container are independent. A developer may create a secret named db_password but configure the service to mount it at /run/secrets/password, while the application expects /run/secrets/db_password.
How to avoid: Define a consistent naming convention for secrets and their targets. Use docker service inspect --pretty to confirm the target path, and always test with cat /run/secrets/<expected-path> inside a container.
4. Assuming the VIP is a Real IP
Why it happens: The service VIP is a virtual IP managed by Docker's routing mesh. It is not bound to any single container. Some users try to ping the VIP or connect to it from outside the overlay and get confused when it works only from within the network.
How to avoid: Understand that the VIP is only routable from containers on the same overlay network. For external access, use a published port.
5. Not Checking Service Replica Status
Why it happens: A service may be defined but have zero running replicas due to failed tasks. DNS might still resolve the service name to a VIP, but no backend container exists to handle traffic.
How to avoid: Always run docker service ps <service-name> before and during troubleshooting. Look for tasks in Running state. If tasks are failing, inspect logs with docker service logs <service-name>.
Decision Ownership and Review Cadence
In a team setting, several decisions and checks should have a clear owner and a regular review cycle.
| Decision or Check | Responsible Role | Review Frequency |
|---|---|---|
| Network topology and overlay design | Infrastructure Lead (e.g., Priya Shah, Engineering Lead) | Quarterly or on major architecture change |
| Secret creation and rotation policy | Security Engineer (e.g., Marcus Chen, Security Engineer) | Every 6 months or after any suspected exposure |
| Service network attachments and port exposures | Application Owner (e.g., David Kim, Backend Lead) | Every sprint planning or when service spec changes |
| Firewall rules for Docker hosts | Systems Administrator (e.g., Elena Rodriguez, SysAdmin) | Monthly or after any infrastructure change |
| Troubleshooting runbook updates | DevOps Engineer (e.g., Tom Okafor, DevOps Engineer) | After every major incident or quarterly |
The frequency can be adjusted to your team's size and risk profile, but having a named person prevents the "everyone thought someone else was doing it" problem.
Operations Checklist
Use this checklist when facing a networking issue with Docker Secrets. Work through it in order, and document what you find at each step.
| Step | Action | Command or Details | Owner |
|---|---|---|---|
| 1 | Verify Docker and Swarm versions | docker version, docker info | On-call engineer |
| 2 | List nodes and networks | docker node ls, docker network ls | On-call engineer |
| 3 | Inspect service configuration | docker service inspect --pretty <service> | App owner |
| 4 | Check secret mounts | docker service inspect --format '{{json .Spec.TaskTemplate.ContainerSpec.Secrets}}' | jq . | Security engineer |
| 5 | Create a test service on the same network | docker service create --name test- --network alpine sleep 3600 | On-call engineer |
| 6 | Test DNS resolution | nslookup inside test container | On-call engineer |
| 7 | Test port connectivity | nc -zv inside test container | On-call engineer |
| 8 | Verify routing | ping , ip route , traceroute | On-call engineer |
| 9 | Check firewall rules | sudo iptables -L DOCKER-USER -n -v on affected hosts | Sysadmin |
| 10 | Review service logs | docker service logs | App owner |
| 11 | Attempt recovery | Apply the relevant fix from Failure Modes section | App owner or on-call |
| 12 | Confirm rollback plan | docker service rollback available, network backup saved | On-call engineer |
After resolving the issue, update the runbook with new findings, and if a rollback was used, schedule a follow-up to implement a permanent fix.
Conclusion
Troubleshooting Docker Secrets networking issues is not magic. It is a methodical process of eliminating layers. Start with a baseline: confirm versions, Swarm health, and network topology. Then inspect the service configuration, including secret mounts and network attachments. Use a test container on the same overlay network to isolate DNS, port, and routing problems. Check host firewalls, because they often get overlooked. When you find the root cause, apply a scoped fix and always have a rollback plan.
Remember to keep the test service isolated from production. Use the operations checklist as a memory aid, and assign clear owners for recurring checks. With practice, you will diagnose most networking issues in minutes rather than hours, and keep your secrets and services running smoothly.
Start with a narrow pilot: pick one service and one network, verify local connectivity, then expand the test. This approach limits risk and builds confidence in the troubleshooting process.