Temporary failure in name resolution

Docker DNS Fails After Host Network Change: name resolution fix

Docker containers lose DNS when the host's network changes because they keep the old resolver. Restart Docker, then clean up /etc/resolv.conf and iptables rules.

You changed your Wi-Fi, plugged into a dock, or fired up a VPN, and now every apt update or pip install inside your container dies with Temporary failure in name resolution. The host resolves fine. The container doesn't. Classic.

I had a client last month whose entire print queue died because their Docker-based print spooler couldn't resolve the label printer's hostname after they moved a laptop between two VLANs. Same error, same cause. Here's what actually fixes it.

Cause 1: Docker daemon is still holding the old DNS config

This is the big one. Docker builds its embedded DNS (the one listening on 127.0.0.11 inside user-defined networks) from whatever resolvers the daemon saw when it started. If you were on 192.168.1.1 for DNS and now you're on a VPN that hands out 10.8.0.1, Docker doesn't notice. It keeps forwarding to a resolver that's now unreachable or filtered.

You can confirm it fast:

docker run --rm alpine cat /etc/resolv.conf
# nameserver 192.168.1.1   <-- stale

docker info | grep -A2 "Server Version"
docker info | grep -i dns

If the nameserver listed is something you can't ping from the host anymore, that's your problem.

The fix

Restart the daemon so it re-reads the current resolver state:

sudo systemctl restart docker

On Docker Desktop (Mac/Windows), quit it from the tray and start it again. The whole VM gets rebuilt and picks up the new DNS.

If you want it to stay fixed across network changes, pin explicit resolvers in /etc/docker/daemon.json:

{
  "dns": ["1.1.1.1", "8.8.8.8"],
  "dns-search": ["yourdomain.local"]
}

Then reload:

sudo systemctl restart docker

Don't put your router's IP in there. It changes. Public resolvers don't. If you need internal names, list both the internal DNS server and a public fallback, in that order.

Cause 2: Broken iptables NAT rules from the old network

Docker inserts NAT rules into the nat table so container traffic can reach the outside world, plus a rule in filter that allows DNS to 127.0.0.11. When your host's default route changes, sometimes the old MASQUERADE rules point at an interface that no longer exists (like wlan0 disappearing when you plug in Ethernet). The container sends the packet, it goes nowhere, and glibc reports the resolution failure.

Check what interface Docker thinks it's using:

sudo iptables -t nat -L POSTROUTING -n -v | grep -i masq
# MASQUERADE  all  --  172.17.0.0/16  !docker0   <-- missing -o eth0

If you see stale references to an interface that's down, that's it.

The fix

The cleanest way is to let Docker rebuild its rules. On Ubuntu/Debian with ufw you'll also want to reset that:

sudo systemctl stop docker
sudo iptables -t nat -F
sudo iptables -t nat -X
sudo iptables -F DOCKER
sudo iptables -F DOCKER-USER
sudo systemctl start docker

# if ufw is in play
sudo ufw reload

Verify the MASQUERADE rule now names a live interface:

sudo iptables -t nat -L POSTROUTING -n -v | grep MASQUERADE

Users running firewalld (Fedora, RHEL, CentOS Stream) should install the Docker firewalld plugin instead of hand-patching rules — Docker's docs cover this and it stops the whole class of breakage.

Cause 3: systemd-resolved stub listener conflict

On Ubuntu 20.04/22.04/24.04 and Fedora, systemd-resolved binds 127.0.0.53:53 and your host's /etc/resolv.conf is a symlink to /run/systemd/resolve/stub-resolv.conf. Docker copies that file into the container at start. If the symlink gets clobbered — NetworkManager sometimes rewrites it, VPN clients love to — the container ends up with a nameserver it can't reach from inside its network namespace.

Verify:

ls -l /etc/resolv.conf
# lrwxrwxrwx ... /etc/resolv.conf -> ../run/systemd/resolve/stub-resolv.conf  <-- good
# -rw-r--r-- ...   <-- bad, some tool overwrote it

resolvectl status | head -20

The fix

Restore the symlink and re-read DNS:

sudo ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
sudo resolvectl flush-caches
sudo resolvectl reset-server-features
sudo systemctl restart docker

If a VPN client is the culprit (Twingate, Tailscale, some enterprise ZTNA agents), check whether it's writing /etc/resolv.conf directly. The real fix there is a daemon.json dns entry that explicitly points at your VPN's resolver — don't rely on Docker inheriting it.

Quick-reference table

SymptomCauseFix
Container /etc/resolv.conf has stale nameserver, host resolves fine Daemon holds old resolver sudo systemctl restart docker and set dns in daemon.json
DNS fails only after switching Wi-Fi/Ethernet/VPN Broken iptables NAT rules Flush nat and DOCKER chains, restart dockerd
/etc/resolv.conf is a regular file, resolvectl misbehaves systemd-resolved symlink clobbered Recreate symlink to stub-resolv.conf, flush caches
Only some containers affected Custom bridge with bad subnet overlap Change subnet in docker network create --subnet, recreate network
Works with IP, not hostname Container on default bridge without DNS Move to a user-defined network so embedded DNS at 127.0.0.11 is used

One more thing that bites people: if you're on Docker Desktop for Windows with WSL2, restarting Docker Desktop isn't always enough after a VPN change. Run wsl --shutdown from PowerShell, then relaunch Docker Desktop. The WSL VM caches its own resolver state and won't pick up the new one otherwise.

If you've done all three and it's still broken, run this from inside a broken container to see exactly where it's dying:

docker run --rm --dns 1.1.1.1 alpine sh -c "apk add --no-cache bind-tools && dig +short google.com @1.1.1.1"

If that works but the default doesn't, DNS is fine — your container's resolver config isn't. That narrows it to Cause 1 almost every time.

Related Errors in Network & Connectivity
0XC0020040 Fix RPC_NT_INVALID_NAF_ID (0XC0020040) in Windows 0X80340011 0x80340011 NDIS Adapter Not Ready — Real Fixes 0XC0230009 Fix STATUS_NDIS_MULTICAST_FULL (0xC0230009) in VMs 0X00002756 WSAESTALE (0x00002756) – Stale File Handle Error Fix

Was this solution helpful?

EP
Erropedia Team
Tech Support Editors
The Erropedia editorial team researches and documents real-world tech errors from across Windows, Linux, macOS, networking, databases, cloud platforms, and more. Every solution is reviewed for accuracy and updated as software and systems evolve.