Cannot access app running on WSL2 by localhost

August 10, 2022

This suddenly just happened. The only significant change I did was running WSL with Docker for Desktop. I was able to run apps inside the Docker container and access them from the Windows host but then I noticed I can no longer access the non-docker apps. They suddenly returned ERR_NO_RESPONSE (or something, I forgot) and ERR_CONNECTION_RESET when trying to access them by localhost:port.

wsl-localhost-err-connection-reset

Things I have tried:

  • Uninstalled docker
  • Removed entries added by Docker in Windows hosts file (C:\Windows\System32\drivers\etc\hosts)
  • Reinstalled WSL
What worked

But what worked is that I have to run this powershell script starting WSL.

Previously, I never had to do this, I only ran this once before and opening localhost:port apps never had an issue. Only recently after touching Docker that I have to run this every time.

wsl2-ports.ps1
$remoteport = bash.exe -c "ifconfig eth0 | grep 'inet '"
$found = $remoteport -match '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}';
if( $found ){
$remoteport = $matches[0];
} else{
echo "The Script Exited, the ip address of WSL 2 cannot be found";
exit;
}
#[Ports]
#All the ports you want to forward separated by coma
$ports=@(80,443,3000,5000,9000,10000,19000,19001,8888);
#[Static ip]
#You can change the addr to your ip config to listen to a specific address
$addr='0.0.0.0';
$ports_a = $ports -join ",";
#Remove Firewall Exception Rules
iex "Remove-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' ";
#adding Exception Rules for inbound and outbound Rules
iex "New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Outbound -LocalPort $ports_a -Action Allow -Protocol TCP";
iex "New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Inbound -LocalPort $ports_a -Action Allow -Protocol TCP";
for( $i = 0; $i -lt $ports.length; $i++ ){
$port = $ports[$i];
iex "netsh interface portproxy delete v4tov4 listenport=$port listenaddress=$addr";
iex "netsh interface portproxy add v4tov4 listenport=$port listenaddress=$addr connectport=$port connectaddress=$remoteport";
}

The code is from this comment ↗️ on a Github issue.

You can run the script by opening CMD as admin. This will add Inbound and Outbound rules in the Firewall for WSL.

Terminal window
powershell -ExecutionPolicy Bypass -File wsl2-ports.ps1

When trying to run the command in CMD, you might encounter an error ifconfig: command not found. To fix this, run sudo apt install net-tools inside WSL. This will also make ifconfig accessible to CMD.

So my new workflow right now is:

  • Open WSL
  • Run the powershell script
  • Run the apps and access them on localhost

A bit tedious but 🤷‍♂️.

Default Values

For reference, I ended up not touching these files. I read some solutions that changed these files but not on my case.

/etc/resolv.conf
# This file was automatically generated by WSL. To stop automatic generation of this file, add the following entry to /etc/wsl.conf:
# [network]
# generateResolvConf = false
nameserver 172.31.32.1

If your WSL can’t access the internet, change the nameserver to 8.8.8.8.

/etc/hosts
# This file was automatically generated by WSL. To stop automatic generation of this file, add the following entry to /etc/wsl.conf:
# [network]
# generateHosts = false
127.0.0.1 localhost
127.0.1.1 DESKTOP-VA2HL43.localdomain DESKTOP-VA2HL43
127.0.0.1 localhost
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

Windows\System32\drivers\etc\hosts
# Copyright (c) 1993-2009 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example:
#
# 102.54.94.97 rhino.acme.com # source server
# 38.25.63.10 x.acme.com # x client host
# localhost name resolution is handled within DNS itself.
# 127.0.0.1 localhost
# ::1 localhost
127.0.0.1 localhost
# Added by Docker Desktop
# 192.168.1.4 host.docker.internal
# 192.168.1.4 gateway.docker.internal
# To allow the same kube context to work on the host and the container:
# 127.0.0.1 kubernetes.docker.internal
# End of section

This is still Day 0 of the workaround and I still need to reinstall Docker again. So we’ll see.


Update history:

  • Oct 26, 2022 - add sudo apt install net-tools
  • Dec 05, 2024 - I haven’t experienced this since then. I’m also on Windows 11 now