Things don't always work on the first try. This guide covers the most common WSL2 GUI problems and how to fix them, organised by whether you're using WSLg (individual apps) or XRDP (full desktop).
General Issues
These problems affect both WSLg and XRDP setups.
The ACPI Problem
If you've installed a full desktop package like ubuntu-desktop, you've probably seen this:
Starting acpid: failed
Could not open /proc/acpi/eventThis isn't a bug in your setup. It's a fundamental mismatch between what desktop packages expect and what WSL2 provides.
Why It Happens
Desktop packages pull in services designed for real hardware:
| Service | Purpose | Why It Fails in WSL2 |
|---|---|---|
| acpid | Power events (lid close, power button) | No physical hardware |
| thermald | CPU thermal throttling | No thermal sensors |
| upower | Battery status | No battery |
| bluetooth | Bluetooth stack | No Bluetooth adapter |
| ModemManager | Mobile broadband | No modem |
WSL2 runs in a lightweight VM. There's no lid to close, no battery to monitor.
The systemd Loop Problem
With systemd enabled, acpid can cause an infinite loop:
acpid.servicetries to start- Condition check fails:
ConditionVirtualization=!container failed acpid.pathdetects the failure and triggers a restart- Back to step 1
This loop can consume CPU and fill your logs. In severe cases, it can destabilise systemd itself.
The Fix: Mask These Services
Masking tells systemd to never start a service, even if something depends on it:
sudo systemctl mask acpid.service acpid.socket acpid.path
sudo systemctl mask thermald.service
sudo systemctl mask upower.service
sudo systemctl mask bluetooth.service
sudo systemctl mask ModemManager.serviceThis is better than removing packages because:
- Dependencies won't try to reinstall them
- You can unmask later if needed
To unmask:
sudo systemctl unmask acpid.service acpid.socket acpid.pathPrevent During Installation
If you haven't installed your desktop yet:
sudo apt install --no-install-recommends ubuntu-desktop-minimal -yThe --no-install-recommends flag skips optional packages like hardware services.
Systemd Issues
Services Won't Start
First verify systemd is running:
cat /proc/1/commIf it shows init, enable systemd:
sudo tee -a /etc/wsl.conf << 'EOF'
[boot]
systemd=true
EOFThen:
wsl --shutdownService Starts But Immediately Stops
Check the logs:
journalctl -u xrdp --no-pager | tail -50
journalctl -u xrdp-sesman --no-pager | tail -50Common causes:
- Missing dependencies
- Port already in use
- Permission issues
Memory Management
Running a desktop uses memory. Control it with .wslconfig.
Create C:\Users\YourName\.wslconfig:
[wsl2]
memory=8GB
processors=4
swap=2GBApply changes:
wsl --shutdownMonitor Usage
Inside WSL:
free -hFrom Windows, check Task Manager for "Vmmem".
WSL Shutting Down During RDP Session
If your distro shuts down while you're connected via RDP, WSL's idle timeout is the cause. WSL doesn't recognize RDP connections as "active usage"—it only tracks terminal sessions.
Symptoms
- Desktop freezes or disconnects after ~15 seconds of inactivity
- Distro shows as stopped in
wsl -l -v - Works fine when a terminal window is also open
Understanding WSL's Two Timeouts
WSL has two separate idle timeouts—you need to disable both:
| Setting | Section | Default | What It Controls |
|---|---|---|---|
instanceIdleTimeout | [general] | 15 seconds | How long an instance stays alive after all user processes exit |
vmIdleTimeout | [wsl2] | 60 seconds | How long the VM stays alive after all instances terminate |
When you connect via RDP without a terminal, WSL considers the instance "idle" (no tracked processes). After 15 seconds, it terminates the instance. Setting only vmIdleTimeout=-1 keeps the VM running but doesn't prevent instance termination.
The Fix: Disable Both Timeouts
Create or edit C:\Users\YourName\.wslconfig:
[general]
instanceIdleTimeout=-1
[wsl2]
vmIdleTimeout=-1Apply the change:
wsl --shutdownThe -1 value disables timeouts completely. Alternatively, set a long timeout in milliseconds (e.g., 86400000 for 24 hours).
Note:
instanceIdleTimeoutwas added in WSL 2.4.4. If you're on an older version, update WSL:wsl --update
Alternative: Keep a Terminal Open
Keep a Windows Terminal tab open to the distro while using RDP. This counts as an active session and prevents shutdown.
Network Managers Breaking WSL Mirrored Networking
If you're using networkingMode=mirrored in your .wslconfig and installed a desktop environment, you may find networking suddenly stops working—not just in the distro with the desktop, but in all your WSL distros.
Symptoms
$ ip -br addr
lo UNKNOWN 127.0.0.1/8 ::1/128
eth0 UP # <-- No IP address!
eth1 UP
eth2 UP
$ ping 8.8.8.8
ping: connect: Network is unreachableThe interfaces are UP but have no IP addresses assigned, and the routing table is empty.
The Culprit: ConnMan and Friends
Desktop environments often install network management daemons:
| Desktop | Network Manager | Problem |
|---|---|---|
| LXQt | ConnMan | Tries to manage interfaces, conflicts with WSL |
| GNOME | NetworkManager | Can interfere with mirrored networking |
| KDE | NetworkManager | Same issue |
These services assume they're running on real hardware and try to configure networking themselves, which breaks WSL's mirrored networking mode.
How to Diagnose
Check what network services are running:
systemctl list-units --type=service --state=running | grep -iE 'network|connman|nm'If you see connman.service or NetworkManager.service, that's likely your problem.
The Cross-Distro Test
To confirm, try this:
wsl --shutdownfrom Windows- Start a minimal distro (one without a desktop):
wsl -d <other-distro> - Check networking—it should work
- Now start your desktop distro:
wsl -d <desktop-distro> - Go back to the minimal distro and check networking again
If networking breaks in the minimal distro after starting the desktop distro, you've confirmed the issue.
The Fix
Disable and mask the offending service:
# For ConnMan (LXQt, Enlightenment)
sudo systemctl disable --now connman
sudo systemctl mask connman
# For NetworkManager (GNOME, KDE)
sudo systemctl disable --now NetworkManager
sudo systemctl mask NetworkManagerAfter masking, restart WSL:
wsl --shutdownNetworking should now work reliably across all distros.
Optimising Services for WSL Performance
Desktop environments install many services designed for physical hardware. In WSL, these waste resources and can cause slowdowns or failures.
Services to Disable
Run this to disable unnecessary services:
sudo systemctl disable --now \
sddm \
snapd snapd.socket \
avahi-daemon avahi-daemon.socket \
bluetooth \
ofono dundee \
wpa_supplicant \
switcheroo-control \
unattended-upgrades \
preload \
udisks2 \
upower
# Mask them to prevent reactivation
sudo systemctl mask \
sddm \
snapd snapd.socket \
avahi-daemon avahi-daemon.socket \
bluetooth \
ofono dundee \
wpa_supplicant \
switcheroo-controlWhy Each Service Is Unnecessary
| Service | Purpose | Why Disable in WSL |
|---|---|---|
| sddm/gdm/lightdm | Display manager | Using XRDP instead |
| snapd | Snap packages | Slow, snaps have X auth issues |
| avahi-daemon | mDNS/Bonjour | Can conflict with WSL networking |
| bluetooth | Bluetooth stack | No Bluetooth in WSL |
| ofono/dundee | Telephony/DUN | No modem in WSL |
| wpa_supplicant | WiFi management | No WiFi in WSL |
| switcheroo-control | GPU switching | Not applicable |
| unattended-upgrades | Auto updates | Can cause random slowdowns |
| preload | Readahead daemon | Can cause issues in VMs |
| udisks2 | Disk management | Not needed for WSL mounts |
| upower | Power management | No battery in WSL |
Checking the Result
After disabling, check what's still running:
systemctl list-units --type=service --state=running | wc -lA well-optimised WSL desktop distro should have around 15-20 running services, not 30+.
Check system load:
uptime
free -hYou should see low load averages (under 0.5) and reasonable memory usage.
Virtual Disks Showing in File Manager
When running a desktop environment, you may see devices like /dev/sda, /dev/sdb, etc. in your file manager's sidebar. These are WSL2's virtual block devices—not your Windows drives.
What These Devices Are
| Device | What It Is |
|---|---|
/dev/sda | WSL2's root filesystem (ext4 virtual disk) |
/dev/sdb, /dev/sdc, etc. | Windows drives mounted as virtual block devices |
Your actual Windows files are at /mnt/c, /mnt/d, etc.—not these block devices.
Clicking on /dev/sdX devices prompts for a password because the file manager tries to mount them as removable drives, which doesn't work in WSL.
Hide in File Manager Settings
Thunar (XFCE): Edit → Preferences → Side Pane → uncheck device options, or right-click device → "Unmount and Eject"
Caja (MATE): Edit → Preferences → Sidebar → adjust "Show" options
Dolphin (KDE): Right-click sidebar → "Hide Section" or configure in Places panel settings
Access Windows Files Correctly
Your Windows drives are at:
/mnt/c # C: drive
/mnt/d # D: drive
# etc.Add bookmarks to these paths in your file manager for easy access.
XRDP Troubleshooting
Issues specific to running a full Linux desktop via XRDP.
Black Screen After Login
The most common XRDP problem. You connect, enter credentials, then... nothing but black.
Cause 1: Missing or Wrong .xsession
XRDP doesn't know which desktop to start:
cat ~/.xsessionShould contain your desktop's start command. Create or fix it:
# For XFCE
echo "startxfce4" > ~/.xsession
# For MATE
echo "mate-session" > ~/.xsession
# For LXQt
echo "startlxqt" > ~/.xsessionCause 2: startwm.sh Conflicts
XRDP's default startup script can conflict with your session configuration. Edit it:
sudo nano /etc/xrdp/startwm.shComment out these lines near the bottom:
# test -x /etc/X11/Xsession && exec /etc/X11/Xsession
# exec /bin/sh /etc/X11/XsessionAdd your desktop command:
startxfce4Cause 3: GNOME Needs Extra Configuration
GNOME requires environment variables. See the GNOME Desktop Not Working section below.
Cause 4: Same User Logged In Elsewhere
If you're logged in via WSLg and try to connect via XRDP with the same user, you may get a black screen. Log out of WSLg first, or use a different user for XRDP.
Cause 5: D-Bus Not Running
Desktop environments need D-Bus:
sudo service dbus statusIf not running:
sudo service dbus startWith systemd:
sudo systemctl start dbusCause 6: WSLg Environment Variables Conflict
This is a subtle one. If WSLg is enabled, it sets environment variables that leak into your XRDP session, causing apps to try connecting to the wrong display server.
How to diagnose:
Check your session errors after a failed login:
cat ~/.xsession-errorsIf you see errors like:
xfwm4: cannot open display: wayland-0
Or anything referencing wayland-0 when you're trying to run an X11 session, WSLg is interfering.
What's happening:
WSLg sets these variables system-wide:
| Variable | WSLg Value | XRDP Expects |
|---|---|---|
DISPLAY | :0 | :10 (or similar) |
WAYLAND_DISPLAY | wayland-0 | (not set) |
When XRDP starts your session, these WSLg variables persist and confuse X11 applications—they try to connect to Wayland or the wrong X display.
Why unsetting in scripts doesn't reliably work:
You might think adding unset WAYLAND_DISPLAY to ~/.xsession or /etc/xrdp/startwm.sh would fix this. Sometimes it does, but the variables can be re-set by profile scripts or the compositor itself before your desktop fully starts.
The reliable fix:
Disable WSLg entirely if you're using XRDP for your desktop. Create or edit C:\Users\YourName\.wslconfig:
[wsl2]
guiApplications=falseThen restart WSL:
wsl --shutdownNow reconnect via XRDP. The environment variables won't be set, and your X11 session will work.
Trade-off: With guiApplications=false, you lose WSLg—you can't run individual Linux GUI apps on your Windows desktop anymore. If you need both WSLg for casual app use and XRDP for full desktop sessions, you'll need to toggle this setting and restart WSL when switching between them.
Cause 7: X11 Socket Directory Is a Dangling Symlink
Even with guiApplications=false, WSL's init system may create /tmp/.X11-unix as a symlink pointing to /mnt/wslg/.X11-unix. Since WSLg is disabled, that target doesn't exist—leaving a dangling symlink that breaks XRDP.
How to diagnose:
Check what /tmp/.X11-unix is:
ls -la /tmp/.X11-unixIf it shows a symlink to /mnt/wslg/.X11-unix, that's the problem:
lrwxrwxrwx 1 root root 19 Jan 22 16:09 /tmp/.X11-unix -> /mnt/wslg/.X11-unix
Check the XRDP session manager log:
cat /var/log/xrdp-sesman.log | grep -i "X11-unix"You'll see errors like:
[ERROR] sesman.c: error creating dir /tmp/.X11-unix
Where the symlink comes from:
- WSL's init creates it when booting, even when
guiApplications=false(race condition or cached state) - Win-KeX on Kali recreates the symlink when
kex stopruns via itswslg-sock restorefunction
The fix:
sudo rm /tmp/.X11-unix
sudo mkdir /tmp/.X11-unix
sudo chmod 1777 /tmp/.X11-unix
sudo systemctl restart xrdpMaking it permanent (symlink returns on WSL restart):
Add a boot command to /etc/wsl.conf:
[boot]
systemd=true
command=/bin/bash -c "[ -L /tmp/.X11-unix ] && rm /tmp/.X11-unix && mkdir -p /tmp/.X11-unix && chmod 1777 /tmp/.X11-unix"This runs before systemd starts services, fixing the symlink before XRDP tries to use it.
Connection Refused
You can't connect at all—Remote Desktop says the connection was refused.
Check XRDP Is Running
sudo service xrdp statusIf not running:
sudo service xrdp startOr with systemd:
sudo systemctl start xrdpCheck the Port
sudo grep "^port=" /etc/xrdp/xrdp.iniMake sure you're connecting to the right port. If it says port=3390, connect to localhost:3390.
Check for Port Conflicts
sudo ss -tlnp | grep 3390If nothing is listening, XRDP isn't running properly. Check logs:
sudo journalctl -u xrdp -u xrdp-sesman --no-pager | tail -50Authentication Failures
You enter your password but it's rejected.
Set a Password
WSL users sometimes don't have passwords set:
sudo passwd $(whoami)Enter a new password when prompted.
Check PAM Configuration
XRDP uses PAM for authentication. Make sure it's configured:
ls -la /etc/pam.d/xrdp-sesmanIf missing, reinstall xrdp:
sudo apt install --reinstall xrdpGNOME Desktop Not Working
If you installed ubuntu-desktop hoping for a full GNOME experience over XRDP, you'll likely hit several issues.
GNOME Shell Requires 3D Acceleration
GNOME Shell (the default Ubuntu desktop) requires OpenGL hardware acceleration. XRDP's Xorg doesn't provide this. You'll see errors like:
gnome-session-check-accelerated: GL Helper exited with code 512
gnome-session-check-accelerated: GLES Helper exited with code 512The fix: Use GNOME Flashback instead, which works with software rendering:
sudo apt install gnome-session-flashback -yCreate a proper .xsession that sources your environment before starting the session:
cat > ~/.xsession << 'EOF'
#!/bin/sh
# Source environment for XDG_CURRENT_DESKTOP
if [ -r ~/.xsessionrc ]; then
. ~/.xsessionrc
fi
exec gnome-session --session=gnome-flashback-metacity
EOF
chmod +x ~/.xsessionCreate .xsessionrc with the correct desktop identifier (this is critical for gnome-panel to autostart):
cat > ~/.xsessionrc << 'EOF'
export XDG_CURRENT_DESKTOP=GNOME-Flashback:GNOME
export XDG_CONFIG_DIRS=/etc/xdg/xdg-ubuntu:/etc/xdg
EOFThe default /etc/xrdp/startwm.sh should work with this setup—it will execute your .xsession file.
Desktop Portal Services Timeout
Even with GNOME Flashback, you may experience extreme slowness—apps taking minutes to open. Check the journal:
journalctl --user -b | grep -i timeoutIf you see messages like:
xdg-desktop-portal.service: start operation timed out
xdg-desktop-portal-gnome.service: Failed with result 'timeout'
Failed to activate service 'org.freedesktop.impl.portal.desktop.gnome': timed outThese portal services (used for sandboxed app features like file pickers) don't work properly in WSL2 and take 2 minutes to timeout on every operation.
The fix: Mask the problematic services:
# User services
systemctl --user mask xdg-desktop-portal.service
systemctl --user mask xdg-desktop-portal-gnome.service
systemctl --user mask xdg-desktop-portal-gtk.service
# System service
sudo systemctl mask ModemManager.serviceRestart WSL after masking:
wsl --shutdownTrade-off: Some GTK file dialogs in sandboxed apps may not work, but the desktop will be responsive.
GNOME Panel Not Appearing
You get a desktop with GNOME Flashback but no panel (taskbar/menu). This happens when XDG_CURRENT_DESKTOP isn't set correctly.
The gnome-panel desktop file contains OnlyShowIn=GNOME-Flashback; so it only autostarts when the desktop environment is correctly identified.
Two things must be true:
- Your
.xsessionrcmust set the correct value:
cat ~/.xsessionrc
# Should show: export XDG_CURRENT_DESKTOP=GNOME-Flashback:GNOME- Your
.xsessionmust actually source.xsessionrc:
cat ~/.xsession
# Should include: . ~/.xsessionrc (before the exec line)If either is wrong, recreate both files as shown in the "GNOME Shell Requires 3D Acceleration" section above, then disconnect and reconnect via RDP.
Snap Apps Don't Work (Firefox, etc.)
Ubuntu ships Firefox as a snap package. Snaps have X authentication issues with XRDP sessions:
Authorization required, but no authorization protocol specified
Error: cannot open display: :10.0The fix: Replace snap Firefox with the .deb version from Mozilla's PPA:
# Remove snap version
sudo snap remove firefox
# Add Mozilla PPA
sudo add-apt-repository -y ppa:mozillateam/ppa
# Prioritize PPA over snap
sudo tee /etc/apt/preferences.d/mozilla-firefox << 'EOF'
Package: *
Pin: release o=LP-PPA-mozillateam
Pin-Priority: 1001
EOF
# Install deb version
sudo apt update
sudo apt install -y --allow-downgrades firefoxThis applies to other snap applications too. If an app won't launch over XRDP, check if it's a snap (snap list) and look for a .deb alternative.
Recommendation: Use a Lighter Desktop
GNOME, even in Flashback mode, has many background services that struggle in WSL2. For the smoothest XRDP experience, consider using XFCE or MATE instead—they have fewer dependencies and work reliably without these workarounds.
WSLg Troubleshooting
Issues specific to running individual Linux GUI apps via WSLg.
"Cannot Open Display"
Linux GUI apps fail with display errors.
Check DISPLAY Variable
echo $DISPLAYShould output :0. If empty or wrong:
export DISPLAY=:0Restart WSL
The nuclear option that fixes most WSLg issues:
wsl --shutdownThen reopen your terminal.
Check WSL Version
WSLg only works with WSL 2:
wsl.exe -l -vYour distro should show "2" under VERSION. If it shows "1":
wsl --set-version <distro-name> 2Remove Old X Server Configuration
If you previously used VcXsrv or X410, old configuration might conflict:
# Check for manual DISPLAY exports
grep -r "DISPLAY" ~/.bashrc ~/.profile ~/.zshrc 2>/dev/nullRemove any lines that set DISPLAY to something other than :0.
Black Windows or Rendering Issues
Apps open but display incorrectly.
Update GPU Drivers
WSLg uses GPU acceleration. Driver bugs cause rendering problems.
- NVIDIA: Download from nvidia.com/drivers
- AMD: Download from amd.com/support
- Intel: Check Windows Update or download from intel.com/download-center
Check GPU Is Detected
Inside WSL:
glxinfo | grep "OpenGL renderer"You should see your GPU name. If you see "llvmpipe", that's software rendering—fine for most apps, but 3D-heavy applications will be slower.
Disable GPU Acceleration (Workaround)
If GPU issues persist, you can disable acceleration:
export LIBGL_ALWAYS_SOFTWARE=1
your-app &Not ideal for performance, but it rules out driver issues.
Audio Not Working
No sound from Linux applications.
Check PulseAudio
pactl infoIf it fails or shows errors, restart WSL:
wsl --shutdownCheck PULSE_SERVER
echo $PULSE_SERVERShould be /mnt/wslg/PulseServer. If different, you may have old configuration overriding it.
Reference
Log File Locations
When troubleshooting, check these logs:
| Log | Location | What It Contains |
|---|---|---|
| XRDP main | /var/log/xrdp.log | Connection attempts, errors |
| XRDP session | /var/log/xrdp-sesman.log | Session creation, authentication |
| Xorg XRDP | ~/.xorgxrdp.*.log | Display server issues |
| Session errors | ~/.xsession-errors | Desktop startup failures |
| systemd | journalctl -u <service> | Service-specific logs |
View Recent XRDP Activity
# XRDP connection log
sudo tail -50 /var/log/xrdp.log
# Session manager log
sudo tail -50 /var/log/xrdp-sesman.log
# Your session errors
cat ~/.xsession-errors
# Xorg logs (the number varies)
cat ~/.xorgxrdp.*.log 2>/dev/nullCommon Error Messages
| Error | Cause | Fix |
|---|---|---|
cannot open display :0 | DISPLAY not set or WSLg not running | export DISPLAY=:0 or restart WSL |
cannot open display: wayland-0 | WSLg env vars leaking into XRDP | Disable WSLg in .wslconfig |
GL Helper exited with code 512 | GNOME Shell needs 3D acceleration | Use gnome-session-flashback instead |
xdg-desktop-portal: timed out | Portal services failing in WSL2 | Mask portal services with systemctl |
Authorization required, but no authorization protocol specified | Snap app can't access X display | Install .deb version instead of snap |
Connection refused | XRDP not running | sudo service xrdp start |
ACPI: Unable to locate RSDP | Hardware service in VM | sudo systemctl mask acpid |
Failed to connect to session bus | D-Bus not running | sudo service dbus start |
Authentication failed | No password or wrong password | sudo passwd $(whoami) |
xrdp-sesman: bind failed | Port already in use | Change port or kill conflicting process |
Quick Diagnostic Script
Run this to gather diagnostic information:
echo "=== WSL Version ==="
wsl.exe --version 2>/dev/null || echo "Run from Windows: wsl --version"
echo -e "\n=== Init System ==="
cat /proc/1/comm
echo -e "\n=== DISPLAY ==="
echo $DISPLAY
echo -e "\n=== XRDP Status ==="
sudo service xrdp status 2>/dev/null || systemctl status xrdp 2>/dev/null
echo -e "\n=== XRDP Port ==="
grep "^port=" /etc/xrdp/xrdp.ini 2>/dev/null
echo -e "\n=== Masked Services ==="
systemctl list-unit-files --state=masked 2>/dev/null | grep -E "acpi|thermal|upower|bluetooth|modem"
echo -e "\n=== .xsession ==="
cat ~/.xsession 2>/dev/null || echo "Not found"
echo -e "\n=== Recent XRDP Errors ==="
sudo tail -10 /var/log/xrdp.log 2>/dev/nullNuclear Option: Reset Everything
If you've made a mess and want to start fresh:
# Remove desktop and XRDP
sudo apt remove --purge xfce4* xrdp ubuntu-desktop* gnome* kde* -y
sudo apt autoremove -y
# Clean up configs
rm -rf ~/.xsession ~/.xsessionrc ~/.Xauthority
rm -rf ~/.config/xfce4 ~/.config/gnome* ~/.config/kde*
rm -rf ~/.xorgxrdp.*.log ~/.xsession-errors
# Reinstall cleanly
sudo apt update
sudo apt install xfce4 xrdp -y
sudo sed -i 's/^port=3389/port=3390/' /etc/xrdp/xrdp.ini
echo "startxfce4" > ~/.xsession
sudo systemctl enable xrdp --nowOr for a complete reset, delete and recreate the distro:
# WARNING: Destroys all data in the distro
wsl --unregister Ubuntu
wsl --install -d UbuntuThis Series
- Part 1: Running Linux GUI Apps with WSLg
- Part 2: Ubuntu Desktop with XRDP
- Part 3: Fedora Desktop with XRDP
- Part 4: Kali Linux Desktop with Win-KeX
- Part 5: Arch Linux Desktop with XRDP
- Part 6: openSUSE Desktop with XRDP
- Part 7: Alpine Linux Desktop with XRDP
- Part 8: WSL2 Desktop Troubleshooting Guide — You are here
Further Reading
- WSLg Troubleshooting Wiki
- XRDP GitHub Issues — Search for your error
- Microsoft WSL Troubleshooting