Quick fix
# Immediate recovery (systemd distro, Ubuntu 22.04+): give the stub a reachable upstream and apply it
sudo sed -i 's/^#*DNS=.*/DNS=223.5.5.5 119.29.29.29/' /etc/systemd/resolved.conf
sudo systemctl restart systemd-resolved
getent hosts github.com # returns an IP = fixed
# Non-systemd distro: write resolv.conf directly (may be overwritten on restart, see "Step by step" for the permanent fix)
sudo sh -c 'echo "nameserver 223.5.5.5" > /etc/resolv.conf'
What you will run into
Inside WSL, curl / git clone / apt update report Temporary failure in name resolution (or Could not resolve host), while Windows itself has working internet; typical scenarios: VPN connects, WSL immediately loses network;
or every WSL restart, /etc/resolv.conf gets rewritten by Windows to a dead address.
Diagnosis mantra: first separate "name resolution broken" from "route broken" — ping 8.8.8.8 works but ping github.com fails with a resolution error = DNS problem, which is what this page covers.
Why this happens
Conclusion first: this does not mean WSL is broken — it means "DNS upstream unreachable". The resolution chain can only break at three points: resolv.conf overwritten, stub upstream unreachable, or the NAT channel broken by the VPN.
Below is the chain, so you can pinpoint yours.
The chain: DNS is "copied" from the Windows side into WSL.
WSL2 networking is a NAT virtual switch: WSL has no physical NIC of its own, so DNS depends on the Windows side. With generateResolvConf=true, WSL rewrites /etc/resolv.conf on every start.
On systemd distros (Ubuntu 22.04+), /etc/resolv.conf points at the stub 127.0.0.53 — the stub does not resolve anything itself, it just forwards queries to its upstream. That upstream comes from the Windows-side DNS, visible via resolvectl status.
The VPN trap: the upstream is only reachable inside the tunnel.
When the VPN connects, Windows copies the VPN's DNS into WSL. Those servers only exist inside the tunnel, so the stub forwards outside the tunnel and fails — hence Temporary failure in name resolution.
Three breakpoints map to three fix families:
- resolv.conf overwritten or incorrect → pin it:
generateResolvConf=false+ a manual nameserver; - stub upstream unreachable (typically: VPN DNS inside the tunnel) → swap the upstream:
DNS=in/etc/systemd/resolved.conf, orresolvectl; - NAT forwarding itself broken by the VPN → bypass the NAT DNS path:
dnsTunneling=truein.wslconfig(queries handled Windows-side) ornetworkingMode=mirrored(WSL shares the Windows network stack).
Note: generateResolvConf=false only prevents "being overwritten", not "upstream reachable" — it fixes breakpoint 1, not breakpoints 2 and 3.
Local repro (2026-08-31): resolv.conf = stub (127.0.0.53), upstream = 223.5.5.5/119.29.29.29 (from resolved.conf), getent hosts github.com worked.
After pointing resolv.conf at an unreachable address (203.0.113.1), getaddrinfo raised [Errno -3] Temporary failure in name resolution; restoring it fixed resolution — confirming the "nameserver pointing at an unreachable address = this error" chain.
Deterministic takeaway: run resolvectl status first. Upstream unreachable → switch to a reachable DNS; upstream looks fine but the network is still down → route/tunnel problem (verify with ping 8.8.8.8), investigate dnsTunneling / mirrored.
Step by step
1. Separate DNS from routing — Required (30-second triage)
ping -c1 223.5.5.5 # works = routing is fine; fails = tunnel/virtual-switch problem
getent hosts github.com # works = DNS is fine; "Temporary failure" = DNS problem, continue below
2. Inspect the current resolution chain — Required (know which layer broke)
cat /etc/resolv.conf # stub=127.0.0.53 (systemd) or direct nameserver (non-systemd)
resolvectl status # systemd: look at Current DNS Server / DNS Servers (where upstream comes from)
Upstream is 127.0.0.53 and resolution fails → swap upstream (Quick fix section); resolv.conf itself is a dead address → fix it.
3. Pin resolv.conf against being overwritten — Permanent fix (the generateResolvConf switch)
# /etc/wsl.conf
[network]
generateResolvConf = false
Then wsl --shutdown and reopen.
Note: on systemd distros keep the stub and change the resolved.conf upstream (Quick fix section) — don't manually overwrite the stub with nameserver lines (conflicts with systemd-resolved); manual resolv.conf writing is for non-systemd distros.
4. VPN scenario: switch the channel — Depends on scenario (VPN kills WSL connectivity)
VPN DNS only exists inside the tunnel → when switching to public DNS doesn't help, change the channel:
# %USERPROFILE%\.wslconfig (Windows side)
[wsl2]
dnsTunneling=true # DNS queries handled Windows-side (official recommendation for VPN first)
# networkingMode=mirrored # more thorough: WSL shares the Windows network stack (pick one)
wsl --shutdown, then reopen. The official troubleshooting doc also gives a manual fallback: note the VPN's DNS servers and write them into resolv.conf.
5. Other breakpoints — Investigate (rare but real)
IPv6 disabled (registry DisabledComponents) → WSL networking may misbehave; a syntax error in .wslconfig → the whole section is ignored after wsl --shutdown, and check wsl --version for feature support (dnsTunneling needs WSL 2.2+).
How to confirm it works
getent hosts github.com && curl -I --max-time 8 https://github.com | head -1
# getent returns an IP and curl returns HTTP/2 200 = full chain works
wsl --shutdown && wsl -d Ubuntu # still works after restart = permanent fix succeeded
Other environments
| Environment | Notes |
|---|---|
| Ubuntu 22.04+ (systemd) | Uses the stub; change the resolved.conf upstream; don't manually overwrite resolv.conf |
| Legacy distro (non-systemd) | Write resolv.conf directly + generateResolvConf=false |
| VPN scenario | Public DNS doesn't help → dnsTunneling=true / mirrored (.wslconfig, needs WSL 2.2+) |
| generateResolvConf=false already set | Stops overwrites, but an unreachable upstream still breaks resolution — check resolvectl status |
Symptom
$ curl -I https://github.com
curl: (6) Could not resolve host: github.com
$ apt update
Temporary failure resolving 'archive.ubuntu.com'
$ getent hosts github.com
(no output, exit=2)
Signature: Windows-side internet works; ping 8.8.8.8 works but all hostnames fail to resolve; breaks right when VPN connects; recurs after WSL restart (overwritten).
Cause
Under WSL2 NAT, DNS is delivered from the Windows side: generateResolvConf=true rewrites /etc/resolv.conf on every start; systemd distros use the stub (127.0.0.53) which forwards to upstream; VPN DNS is unreachable outside the tunnel → forwarding fails → Temporary failure in name resolution. Three breakpoints: resolv.conf written wrong/overwritten, stub upstream unreachable, NAT channel broken by VPN.
Solution
- Triage:
ping 223.5.5.5(routing) vsgetent hosts github.com(DNS); 2. systemd distro: setDNS=223.5.5.5 119.29.29.29in/etc/systemd/resolved.conf+systemctl restart systemd-resolved; 3. prevent overwrites:generateResolvConf=falsein/etc/wsl.conf; 4. VPN scenario:.wslconfigdnsTunneling=trueornetworkingMode=mirrored; 5. verify:getent hosts github.com+curl -I, and still works after a WSL restart.
Verification Evidence
- Local repro (2026-08-31, custom prebuilt WSL; the DNS mechanism is version-independent): local repro log 2026-08-31
- Baseline: resolv.conf=stub (127.0.0.53), resolved.conf upstream=223.5.5.5/119.29.29.29,
getent hosts github.com→ 20.205.243.166; - Repro: resolv.conf pointed at an unreachable address (203.0.113.1) →
getaddrinforaised[Errno -3] Temporary failure in name resolution,getentexit=2; UDP probe: 127.0.0.53 answered normally / 203.0.113.1 timed out; - Recovery: restored resolv.conf → resolution works again (trap fallback + explicit restore, no leftovers);
- The permanent config matches this page's recommendation: wsl.conf
generateResolvConf=false+ public upstream in resolved.conf. - Not tested (honestly noted): VPN scenario (no VPN on this machine), dnsTunneling/mirrored switching (touches the network stack).
Related canonicals
Read in order: precondition -> same root / same domain / related:
- Only one specific website won't open (layer diagnosis) (adjacent: single-domain failures, same layering approach)
- Related (similar errors, different cause):
- This page is the "WSL network/DNS" canonical; adjacent WSL problems: wsl-register-failed (fails at startup), wsl-no-space-left (can't write to disk), wsl-pipe-encoding (garbled output when calling wsl from PowerShell).
Applicable tools (1)
This problem is linked from the tool pages below — reachable from either side.
wslSource & evidence
Source: https://learn.microsoft.com/windows/wsl/troubleshooting (VPN/DNS section) + local repro
Did this fix work for you?
Feedback is aggregated by the maintainer agent for retest scheduling and improvements; anonymous, no personal data.
← Coding Agents & Terminal domain | Problem Catalog Experience | Facing another issue? Go to the Helpdesk