| name | wsl-networking-mode-dns-fallback |
| description | When WSL's mirrored networking fails and falls back to "None", plus /etc/wsl.conf has generateResolvConf=false, the distro has no DNS; fix both layers. |
| tags | ["wsl","networking","dns","windows","apt"] |
WSL networking fallback leaves the distro with no DNS
When to use
You're running something in a WSL2 distro from Windows (apt-get, curl,
git clone, cmake fetching deps, a CI sweep script) and it fails at
name resolution:
Temporary failure resolving 'archive.ubuntu.com'
curl: (6) Could not resolve host: github.com
apt-get update prints W: Failed to fetch ... Temporary failure resolving
getent hosts <anything> returns nothing, exit code 2.
And you see one or both of these on WSL startup:
wsl: An internal error occurred. Error code: CreateInstance/CreateVm/ConfigureNetworking/0x8007054f
wsl: Failed to configure network (networkingMode Mirrored), falling back to networkingMode None.
This is not a transient DNS glitch. The distro is actually
networkless, and /etc/resolv.conf is either missing or stale.
Problem
Two independent misconfigurations combine into a total outage:
-
networkingMode = mirrored in %USERPROFILE%\.wslconfig.
Mirrored mode depends on Hyper-V virtual-switch features that
fail on some Windows builds / VPN / antivirus setups with
ConfigureNetworking/0x8007054f. WSL then "helpfully" falls
back to networkingMode = None, which means no NAT, no vEthernet,
nothing — the distro only has lo and cannot reach the host
network, let alone the internet.
ip addr inside the distro shows only lo and sometimes a
leftover 10.255.255.254/32 on lo (the old mirrored address).
ping 8.8.8.8 → Network is unreachable.
-
generateResolvConf = false in /etc/wsl.conf.
With that flag, WSL will not rewrite /etc/resolv.conf on boot.
Whatever state the file was last left in persists — and if it
was a broken symlink (a common leftover from distros like
systemd-resolved experiments), cat /etc/resolv.conf prints
No such file or directory, and every lookup fails regardless
of the underlying network.
Either one alone would break DNS. Together they look like "WSL is
totally broken" and the error messages don't point at either
config file.
Solution
Fix the two layers in order. All commands run from Windows
PowerShell on the host; the wsl -u root ones execute inside the
distro.
Step 1 — Disable mirrored networking in .wslconfig
Edit %USERPROFILE%\.wslconfig (create it if missing) and either
delete the mirrored block or comment it out:
Keep a backup so you can restore it later once the host-side bug is
resolved:
Copy-Item $env:USERPROFILE\.wslconfig $env:USERPROFILE\.wslconfig.bak-mirrored
Step 2 — Re-enable resolv.conf generation inside the distro
wsl -d <Distro> -u root -- bash -lc @'
cp /etc/wsl.conf /etc/wsl.conf.bak 2>/dev/null || true
sed -i 's/^generateResolvConf\s*=.*/generateResolvConf = true/' /etc/wsl.conf
echo '--- /etc/wsl.conf ---'; cat /etc/wsl.conf
rm -f /etc/resolv.conf
'@
If /etc/wsl.conf didn't already have a [network] section, add one:
wsl -d <Distro> -u root -- bash -lc @'
grep -q "^\[network\]" /etc/wsl.conf || printf "\n[network]\ngenerateResolvConf = true\n" >> /etc/wsl.conf
'@
Step 3 — Shut down and restart WSL
wsl --shutdown
Start-Sleep -Seconds 3
The next wsl invocation creates a fresh VM that (a) uses default
NAT networking instead of mirrored, and (b) regenerates
/etc/resolv.conf automatically.
Step 4 — Verify, in this exact order
Verifying piece-by-piece saves you from chasing red herrings later:
wsl -d <Distro> -- bash -lc @'
echo "--- resolv.conf ---"; cat /etc/resolv.conf 2>/dev/null || echo MISSING
echo "--- interfaces ---"; ip -o -4 addr show
echo "--- DNS ---"; getent hosts archive.ubuntu.com || echo DNS_FAIL
echo "--- HTTP ---"; curl -sS -o /dev/null -w "status=%{http_code} time=%{time_total}s\n" http://archive.ubuntu.com/ubuntu/dists/noble/InRelease
'@
All four must succeed:
| Check | Healthy output |
|---|
resolv.conf | non-empty, starts with the "automatically generated by WSL" comment or a nameserver line |
ip addr | shows eth0 with a routable address (e.g. 172.x.y.z/20), not just lo |
getent hosts | returns one or more IPs |
curl | status=200 |
If resolv.conf comes back but HTTP still fails, the problem is
upstream (corporate proxy, VPN split-tunnel) and not WSL.
Example
Symptoms the reporter actually saw:
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/noble/InRelease
Temporary failure resolving 'archive.ubuntu.com'
cat: /etc/resolv.conf: No such file or directory
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 ...
inet 127.0.0.1/8 scope host lo
inet 10.255.255.254/32 brd 10.255.255.254 scope global lo
DNS_FAIL
Notice the three smoking guns, all visible at once:
- only
lo in ip addr (no eth0) → networkingMode fell back to None,
10.255.255.254/32 on lo → ghost of the failed mirrored mode,
/etc/resolv.conf missing → generateResolvConf = false.
After Steps 1-3, the same diagnostics show eth0 with a 172.x IP,
nameserver 10.255.255.254 in resolv.conf (now a regular file, not
a dead symlink), and curl returns status=200.
Pitfalls
- The fallback message is not harmless noise. Earlier advice
(including a line in the
wsl-bash-crlf-or-tempfile skill)
suggested the Failed to configure network (networkingMode Mirrored), falling back to networkingMode None banner can be ignored — that's
true only if None happens to give you a working interface. On
many hosts None means no network at all; treat the banner as
a hard error and disable mirrored.
wsl --shutdown is mandatory. Editing .wslconfig or
/etc/wsl.conf without shutting down the VM does nothing; the
running VM keeps the old config. Always shutdown + pause a few
seconds before re-entering.
- Don't just
echo nameserver 8.8.8.8 > /etc/resolv.conf. That
"works" for five minutes, then WSL (or the user's next
wsl --shutdown) overwrites or re-breaks it. Fix the generator
flag, not the generated file.
- Check for a broken symlink, not just a missing file. A dangling
/etc/resolv.conf -> ../run/systemd/resolve/stub-resolv.conf looks
like a missing file to cat but like a present file to rm — use
ls -la /etc/resolv.conf before deciding what to do, and rm -f
handles both cases.
- Mirrored mode is still useful when it works. Once you've
confirmed the rest of the toolchain runs under NAT, you can try
re-enabling mirrored on a future Windows update; keep the
.bak
around so you can flip back with a single copy.
- Corporate VPN split-tunnel is a separate failure mode. If
resolv.conf is healthy and eth0 has an IP but curl still
times out, suspect VPN routing; that's out of scope for this
skill.
See also