Skip to content

VcXsrv WSL2 vsock User Guide

millin edited this page Jul 23, 2026 · 3 revisions

VcXsrv WSL2 vsock User Guide


English

This guide shows how to connect X clients in WSL2 to VcXsrv over Hyper-V vsock, replacing the default NAT / localhost-forwarded TCP path.

Why vsock

TCP path vsock path (recommended)
Latency NAT forwarding, limited frame rate; mouse-heavy events stutter noticeably Direct, significantly lower
Sleep/resume, VPN changes Connections may drop Unaffected
Firewall May trigger allow prompts No network stack involved, no prompts

Quick start (3 steps)

Prerequisites: WSL2 (Store WSL 2.0+), socat >= 1.7.4 (sudo apt install socat).

  1. Start VcXsrv on Windows directly from the command line, adding -vsock:

    vcxsrv.exe :0 -multiwindow -clipboard -wgl -vsock
    

    Alternative (XLaunch config): if you prefer not to use the command line, edit config.xlaunch and add ExtraParams="-vsock" to the <XLaunch ...> element (this corresponds to the "Additional parameters for VcXsrv" box in the wizard); keep the shortcut as xlaunch.exe -run config.xlaunch.

  2. In WSL2, start the forwarding socat:

    socat UNIX-LISTEN:/tmp/.X11-unix/X0,fork,mode=777 VSOCK-CONNECT:2:106000 &
    export DISPLAY=:0
    • 2 = VMADDR_CID_HOST, i.e. "the host" (the guest side never needs to know any VM GUID)
    • 106000 = the vsock port, by convention 106000 + display number (:0 → 106000, :1 → 106001)
  3. Run an X program:

    xeyes

Verify:
If the connection really goes over vsock: while the app is running, run ss --vsock | grep '2:106000' — you should see an ESTAB connection.
The startup log (%TEMP%\VCXSrv.0.log) should show: winVsock: WSL2 VM xxxxxxxx-xxxx-... detected, vsock listener enabled

Startup configuration

socat should start with WSL. Pick one of the two:

  • Simple (.bashrc):
if ! pgrep -f "VSOCK-CONNECT:2:106000" >/dev/null; then
    rm -f /tmp/.X11-unix/X0
    socat UNIX-LISTEN:/tmp/.X11-unix/X0,fork,mode=777,forever,retry=10,interval=2 \
          VSOCK-CONNECT:2:106000 &
fi
export DISPLAY=:0

Note: forever,retry lets socat reconnect automatically within seconds after a VcXsrv or WSL restart (together with the server-side automatic rebind, the whole path self-heals). socat does not remove the X0 socket file on exit, so rm -f before restarting it avoids "Address already in use".

  • systemd (for distros with systemd enabled):
# /etc/systemd/system/x11vsock.service
[Unit]
Description=VcXsrv vsock relay
After=multi-user.target

[Service]
ExecStartPre=/bin/rm -f /tmp/.X11-unix/X0
ExecStart=/usr/bin/socat UNIX-LISTEN:/tmp/.X11-unix/X0,fork,mode=777,forever,retry=10000,interval=2 VSOCK-CONNECT:2:106000
Restart=always

[Install]
WantedBy=multi-user.target

Then run sudo systemctl enable --now x11vsock, and export DISPLAY=:0 in /etc/profile.d.

Possible issue: /tmp/.X11-unix/X0 taken by WSLg

On machines with WSLg enabled, /tmp/.X11-unix/X0 is taken by WSLg. Just start VcXsrv on a different display, or disable WSLg:

  • Start VcXsrv on a different display (e.g. :1), and use UNIX-LISTEN:.../X1 + VSOCK-CONNECT:2:106001, export DISPLAY=:1
  • Or disable WSLg (guiApplications=false in .wslconfig)

Other vsock-related options

Goal Option
Bind a specific VM (manual GUID) -vmid {GUID} (get the GUID via wsl.exe -- wslinfo --vm-id; braces required)
Change the vsock base port -vsockport 6000 (then :0 → 6000, :1 → 6001)
Serve regular Hyper-V VMs -listen hyperv (wildcard bind; works for regular VMs, not for WSL2)
Disable vsock entirely -novsock (this is the default; no need to pass it)

For regular Hyper-V VMs: by Microsoft convention, a guest connecting to a host service GUID normally requires the service to be registered in the host registry under HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Virtualization\GuestCommunicationServices\<GUID> (requires admin); the guest uses the same socat relay. Whether unregistered services are accepted depends on the host configuration — test it.

Limitations and notes

  • Self-healing across WSL restarts: after wsl --shutdown, once a distro starts again the server automatically rebinds to the new VM id within about 0.5–1 seconds (no need to restart VcXsrv); with forever,retry, socat reconnects automatically.
  • No cookie: vsock connections are treated as local clients (same trust level as 127.0.0.1); MIT-MAGIC-COOKIE is not required by default. Only the single bound VM can reach the listener.
  • WSL1: has no VM layer and does not support vsock; -vsock simply falls back to TCP silently — no error.
  • Multiple instances: vcxsrv :0 -vsock and vcxsrv :1 -vsock bind 106000/106001 respectively; use X0/X1 socats on the WSL side. Give the second instance -noclipboard to avoid clipboard contention. Two instances can also serve WSL2 and a regular VM separately (one with -vsock, one with -listen hyperv).
  • Running vcxsrv as a different user: the automatic VM id query sees that user's WSL instance.

Troubleshooting

Symptom What to check
Can't open display: :0 Is socat running (pgrep -a socat)? Does DISPLAY match the socket socat created (X0 ↔ :0)? Remove the stale socket (rm -f /tmp/.X11-unix/X0) and restart socat
socat connect ... cid:2 port:106000 ... timed out Was VcXsrv started with -vsock? Is the VM id line in the log? After a WSL restart the old GUID is stale (-vsock rebinds automatically — wait 0.5–1 seconds)
Not sure which path you are on While the app runs, ss --vsock | grep '2:106000' should show ESTAB; or start VcXsrv with -nolisten tcp to rule TCP out
No log lines at all The log is %TEMP%\VCXSrv.<display>.log; make sure WSL is running (Task Manager should show a "Vmmem WSL" process)

Clone this wiki locally