WSL 2: Run Graphical Linux Desktop Applications from Windows 10 Bash Shell "Error E233: cannot open display" [closed]

The networking subsystem in WSL2 is different than the used in WSL1. You must consider the differences to access networking apps running on Windows and on Linux:

  • In WSL1, Linux uses the same IP addresses than the Windows host, then, you can access the applications using localhost or 127.0.0.1
  • In WSL2, Linux runs on a lightweight virtual machine and has a different IP address. To access networking apps running on the Windows Host you must use the Windows IP address.

Checking the IP address of the Windows host

There are many ways to determine the IP addresses in the Windows host. You may run the following commands in your WSL Linux:

  • cat /etc/resolv.conf shows the IP address of the eth0 interface in Windows
  • ipconfig.exe shows the all the IP configuration in the Windows host
  • route.exe print shows the network routing configuration in the Windows host

Setting the DISPLAY variable for WSL2

Based on the Microsoft documentation, you may set the DISPLAY variable checking the nameserver in the /etc/resolv.conf file. (@fqquiner and @VPraharsha already mentioned this)

export DISPLAY=$(grep nameserver /etc/resolv.conf | awk '{print $2}'):0.0

However, I had problems using this solution, probably because I use my notebook with a WiFi connection and multiple virtual networks. Instead of the previous solution, I determine the Windows IP address using route.exe and checking the interface used in the default gateway.

export DISPLAY=$(route.exe print | grep 0.0.0.0 | head -1 | awk '{print $4}'):0.0

Setting the DISPLAY variable in the .profile

You may set the DISPLAY variable in your ~/.profile file. I used the following code:

# set DISPLAY to use X terminal in WSL
# in WSL2 the localhost and network interfaces are not the same than windows
if grep -q WSL2 /proc/version; then
    # execute route.exe in the windows to determine its IP address
    DISPLAY=$(route.exe print | grep 0.0.0.0 | head -1 | awk '{print $4}'):0.0

else
    # In WSL1 the DISPLAY can be the localhost address
    if grep -q icrosoft /proc/version; then
        DISPLAY=127.0.0.1:0.0
    fi

fi

Had the same problem so I tried these other suggestions but what ended up working was allowing vcxsrv through the public firewall. I know you're not using vcxsrv but perhaps it's the same problem for you too.

Install VcXsrv then enable public firewall like these pictures. Open Windows Defender Firewall with Advanced Security using wf.msc at command prompt. Then allow connections like in these pictures.

Double click then allow each of the public profiles for VcXsrv

[Allow the connection in VcXsrv firewall properties2

Then run VcXsrv from this guide for Windows 10 WSL2

Run VcXsrv by adding -ac addition parameter or type this at command prompt "C:\Program Files\VcXsrv\vcxsrv.exe" :0 -multiwindow -clipboard -wgl -ac

Then type this into your WSL2 terminal

export DISPLAY_NUMBER="0.0"
export DISPLAY=$(grep -m 1 nameserver /etc/resolv.conf | awk '{print $2}'):$DISPLAY_NUMBER
export LIBGL_ALWAYS_INDIRECT=1
# OPTIONAL Set the keyboard layout to US
setxkbmap -layout us
setsid emacs
exit

Adding to fquinner's answer,

Your DISPLAY env variable should be set as export DISPLAY=X.X.X.X:0 to use the Windows host's IP address as WSL2 and the Windows host are not in the same network device, where X.X.X.X is the IP address

and your IP address is listed in resolv.conf against the nameserver ($ cat /etc/resolv.conf)

or simply export DISPLAY="`grep nameserver /etc/resolv.conf | sed 's/nameserver //'`:0" to load the correct IP address automatically. Additionally, you can add this to .bashrc or .zshrc (If you use Zsh)


There's a troubleshooting section here for debugging X11 on wsl2:

https://github.com/cascadium/wsl-windows-toolbar-launcher/blob/master/README.md#troubleshooting

Port forwarding is not the same as WSL1 - your Linux services may be accessible via localhost for windows, but the reverse is no longer true.

So you need to use the internal IP of your windows host and tweak the firewall to allow the WSL network through.