Skip to content

[Bug]: WSL backend stuck connecting when Windows can't reach the WSL NAT IP #13738

Description

@Ganboo

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/desktop

Steps to reproduce

  1. On Windows with WSL2 in default NAT networking, run a host where Windows → WSL NAT-IP HTTP is filtered but WSL localhost forwarding works (in my case a corporate endpoint security client intercepts traffic to private ranges).
  2. Enable Settings → WSL backend (dual mode, "WSL only" off) and pick a distro.
  3. Open the command palette and look for Open WSL folder, or try adding a Linux project.

Expected behavior

The desktop connects to the WSL backend and the WSL environment becomes usable, like VS Code/Cursor Remote-WSL on the same machine.

Actual behavior

The WSL backend process starts and is healthy, but the desktop never marks it ready. resolveWslStartConfig sets httpBaseUrl to the distro's hostname -I IP in NAT mode, and every readiness probe to it fails. "Open WSL folder" never appears and WSL projects can't be added.

Measured from the same Windows host against the same backend:

From URL Result
inside WSL http://<wsl-nat-ip>:3774/.well-known/t3/environment 200 in 4ms
Windows http://127.0.0.1:3774/... (wslhost forwarding) 200 in 81ms
Windows http://<wsl-nat-ip>:3774/... (what the desktop uses) TCP connects, then "connection closed unexpectedly" after ~3.7s

Routing is correct (the WSL NAT subnet routes via vEthernet (WSL (Hyper-V firewall)), and eth0 is the default route in the distro), so this isn't the wrong-interface case from #5211. The right IP is chosen but isn't reachable over HTTP from Windows.

For comparison, Cursor's Remote-WSL (anysphere.remote-wsl 1.0.13) on the same machine binds its server to 127.0.0.1 inside WSL and always connects from Windows through http://127.0.0.1:<port>, and it works.

Impact

Blocks work completely

Version or commit

0.0.43-nightly.20260925.2269 (also reproduced on the previous stable release); code path unchanged on main @ 2a9832b80

Environment

Windows 11 Enterprise, WSL2 NAT mode (no .wslconfig), Ubuntu 24.04 distro, T3 Code desktop (dual mode: Windows primary + WSL secondary)

Logs or stack traces

# desktop.trace.ndjson — thousands of these, never succeeding
http.client GET http://<wsl-nat-ip>:3774/.well-known/t3/environment  exit: Failure
# server-child-wsl_<distro>.log — backend itself is healthy
Listening on http://0.0.0.0:3774

Screenshots, recordings, or supporting files

No response

Workaround

Switching WSL to networkingMode=mirrored should make the desktop use loopback, but it changes networking for every distro.

I have a small fix on a branch that I can open as a PR if you want it. For WSL NAT runs it dials 127.0.0.1 first, as VS Code and Cursor do, and keeps the distro IP as a readiness fallback, so hosts where wslhost forwarding is unreliable (the reason for the current behavior) still connect. It's about 60 source lines in DesktopBackendConfiguration.ts and DesktopBackendManager.ts, with focused tests, and I've verified it end to end on the affected machine.

Activity

  1. added
    bugSomething is broken or behaving incorrectly.
    needs-triageIssue needs maintainer review and initial categorization.
    on Sep 26, 2026
  2. Ganboo commented on Sep 26, 2026

    @Ganboo
    Author

    Related

  3. juliusmarminge commented on Sep 26, 2026

    @juliusmarminge
    Member

    The diagnosis matches current main (unchanged in these files since 2a9832b80). In default WSL2 NAT mode, resolveWslStartConfig advertises the distro address from getDistroIp (hostname -I's first IPv4, when that address is not on a Windows interface). waitForHttpReady probes only that URL and retries until it answers, so the WSL environment never connects and "Open WSL folder" stays hidden. The backend can still be healthy on 0.0.0.0, and Windows 127.0.0.1 via wslhost is simply never tried.

    That NAT URL is deliberate. The comment in resolveWslStartConfig records hosts where wslhost forwarding fails and only the distro address works. This report is the inverse: endpoint security drops the NAT address, and localhost forwarding works. It is not #5211 (wrong hostname -I entry). That selection bug is still present, but you already checked that the chosen address is the real eth0 route. #5967 was the same splash without this evidence, so this issue should stay the canonical report.

    #9066 does not fix this. It still advertises the NAT address, and in local-only mode it binds only that address, which removes the WSL loopback listener this host needs. #10358 would help a local-only setup by advertising 127.0.0.1, but it gives up the distro-IP fallback that other machines need.

    A small PR is welcome if it stays on this one behavior: keep the 0.0.0.0 bind, probe 127.0.0.1 first, and fall back to the distro IP when loopback does not answer. The URL that succeeds has to be the one the renderer keeps using. Please include a test for each order, and leave #9056's bind-host change out of it. networkingMode=mirrored remains a working workaround because that mode already forces loopback.

  4. added
    via-triageFiled through npx t3 triage
    acceptedfeature request accepted
    and removed
    needs-triageIssue needs maintainer review and initial categorization.
    on Sep 26, 2026
  5. Ganboo commented on Sep 26, 2026

    @Ganboo
    Author

    Thanks @juliusmarminge made some adjustments and linked my PR above.

    Let me know if any changes are necessary.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    acceptedfeature request acceptedbugSomething is broken or behaving incorrectly.via-triageFiled through npx t3 triage

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions