Coding Agents & Terminal · recorded 2026-08-31 · applies to 1 tool(s) ✓ Verified

Problem: WSL reports Temporary failure in name resolution / no network, and VPN kills WSL connectivity —— Trove problem library

Verified 2026-08-31WSL name resolution fails / network dies when VPN is on — point the systemd stub at reachable upstreams (DNS=223.5.5.5 119.29.29.29) and restart systemd-resolved.

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:

  1. resolv.conf overwritten or incorrect → pin it: generateResolvConf=false + a manual nameserver;
  2. stub upstream unreachable (typically: VPN DNS inside the tunnel) → swap the upstream: DNS= in /etc/systemd/resolved.conf, or resolvectl;
  3. NAT forwarding itself broken by the VPN → bypass the NAT DNS path: dnsTunneling=true in .wslconfig (queries handled Windows-side) or networkingMode=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

EnvironmentNotes
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 scenarioPublic DNS doesn't help → dnsTunneling=true / mirrored (.wslconfig, needs WSL 2.2+)
generateResolvConf=false already setStops 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

  1. Triage: ping 223.5.5.5 (routing) vs getent hosts github.com (DNS); 2. systemd distro: set DNS=223.5.5.5 119.29.29.29 in /etc/systemd/resolved.conf + systemctl restart systemd-resolved; 3. prevent overwrites: generateResolvConf=false in /etc/wsl.conf; 4. VPN scenario: .wslconfig dnsTunneling=true or networkingMode=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) → getaddrinfo raised [Errno -3] Temporary failure in name resolution, getent exit=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.

wsl

Source & evidence

Recorded Verified ✓ VerifiedApplies to 1 tool(s)
Entries contain locally measured or reviewable-source solutions; unmeasured items are explicitly labeled.

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