-
Notifications
You must be signed in to change notification settings - Fork 0
VcXsrv WSL2 vsock User Guide
This guide shows how to connect X clients in WSL2 to VcXsrv over Hyper-V vsock, replacing the default NAT / localhost-forwarded TCP path.
| 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 |
Prerequisites: WSL2 (Store WSL 2.0+), socat >= 1.7.4
(sudo apt install socat).
-
Start VcXsrv on Windows directly from the command line, adding
-vsock:vcxsrv.exe :0 -multiwindow -clipboard -wgl -vsockAlternative (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 asxlaunch.exe -run config.xlaunch. -
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)
-
-
Run an X program:
xeyes
Verify:
If the connection really goes over vsock: while the app is running, runss --vsock | grep '2:106000'— you should see anESTABconnection.
The startup log (%TEMP%\VCXSrv.0.log) should show:winVsock: WSL2 VM xxxxxxxx-xxxx-... detected, vsock listener enabled
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=:0Note:
forever,retrylets 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, sorm -fbefore 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.targetThen run sudo systemctl enable --now x11vsock, and export DISPLAY=:0
in /etc/profile.d.
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 useUNIX-LISTEN:.../X1+VSOCK-CONNECT:2:106001,export DISPLAY=:1 - Or disable WSLg (
guiApplications=falsein.wslconfig)
| 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.
-
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); withforever,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;
-vsocksimply falls back to TCP silently — no error. -
Multiple instances:
vcxsrv :0 -vsockandvcxsrv :1 -vsockbind 106000/106001 respectively; use X0/X1 socats on the WSL side. Give the second instance-noclipboardto 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.
| 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) |