Repository navigation
Description
Windows Version
Microsoft Windows [Version 10.0.26200.9168]
WSL Version
WSL version: 2.7.12.0
Kernel version: 6.18.33.2-2
WSLg version: 1.0.73.2
MSRDC version: 1.2.7214
Direct3D version: 1.611.1-81528511
Are you using WSL 1 or WSL 2?
- WSL 2
- WSL 1
Kernel Version
6.18.33.2-microsoft-standard-WSL2
Distro Version
Affected: Kali GNU/Linux Rolling 2026.3, systemd 261.2-1, no /etc/wsl.conf (PID 1 is init).
Compared on the same host against Debian 12 (systemd 252.39, init) and Ubuntu (systemd 255.4, [boot] systemd=true).
Other Software
None. This reproduces with stock distro package tooling (apt, dpkg, systemd-tmpfiles).
Repro Steps
On a WSLg-enabled distro that does not boot systemd, with systemd >= 261 installed (at least from what I could find):
sudo systemd-tmpfiles --create x11.conf; echo "exit=$?"
# fchmod() of /tmp/.X11-unix failed: Read-only file system
# exit=73sudo apt upgrade then fails at Setting up systemd, leaving the dpkg backlog shown below.
The condition is latent rather than absent on Debian 12. It is hidden only by the ! flag. Forcing that flag to be honoured reproduces the identical failure there:
sudo systemd-tmpfiles --create x11.conf; echo "exit=$?" # exit=0
sudo systemd-tmpfiles --create --boot x11.conf; echo "exit=$?" # exit=73, same fchmod errorThis suggests the affected population grows substantially once distros pick up systemd >= 261 built with debhelper 14.
Expected Behavior
Installing or upgrading the systemd package on a WSLg-enabled distro should complete successfully, the same way it does on a distro where WSL writes /run/tmpfiles.d/x11.conf.
Actual Behavior
Setting up systemd (261.2-1) ...
fchmod() of /tmp/.X11-unix failed: Read-only file system
dpkg: error processing package systemd (--configure):
old systemd package postinst maintainer script subprocess failed with exit status 73
Errors were encountered while processing:
systemd
Error: Sub-process /usr/bin/dpkg returned an error code (1)
systemd is left half-configured and 19 further packages stall unpacked behind it (exim4-*, gvfs*, lightdm, network-manager, openssh-*, stunnel*, libpam-systemd, systemd-sysv). Every retry reproduces identically; the upgrade cannot proceed without manual intervention.
Diagnostic Logs
Not attached. This reproduces deterministically from the one-line repro above, and the failure is entirely in the guest's package-configure path rather than in WSL's own logging.
Summary
WSL already ships a partial fix for this problem: it writes /run/tmpfiles.d/x11.conf to shadow systemd's vendor rule for /tmp/.X11-unix. However, on a WSL distro that does not boot systemd, that file (on my computer) is never written, nothing shadows the vendor rule, and on current systemd + debhelper the result is no longer a harmless boot warning. It fails package configuration and stalls apt completely.
From what I can tell the two conditions WSL already tests before writing that file (enableGuiApps, and /mnt/wslg/runtime-dir existing) are both satisfied on the affected distros. Only the placement of the write appears to prevent it from happening.
Root cause
WSLg bind-mounts the X11 socket directory into the guest read-only:
$ mount | grep X11
none on /tmp/.X11-unix type tmpfs (ro,relatime)
$ ls -ld /tmp/.X11-unix
drwxrwxrwx 2 root root 60 /tmp/.X11-unix
systemd's /usr/lib/tmpfiles.d/x11.conf declares:
D /tmp/.X11-unix 1777 root root 1h
D creates the directory as well as enforces the stated mode. The directory exists at 0777, the rule requires 1777, so systemd-tmpfiles must fchmod(), and this returns EROFS. systemd-tmpfiles exits 73, and the systemd postinst calls it unconditionally at configure time:
# Automatically added by dh_installtmpfiles/14.3
if [ "$1" = "configure" ] || ... ; then
systemd-tmpfiles ${DPKG_ROOT:+--root="$DPKG_ROOT"} --create ... x11.conf
fidpkg sees the non-zero exit and leaves the package half-configured.
Why this is 'new', and why I think it only hits some distros currently
The bug I don't think is truly new. From what I can tell it has existed since WSLg shipped, and what has changed is that it is now fatal, stalls apt and dpkg, instead of being silently swallowed.
I have found three independent things that have historically masked this. If you lose all three then it causes the error. Measured on my local device:
| Debian 12 | Ubuntu | Kali (broken) | |
|---|---|---|---|
| systemd | 252.39 | 255.4 | 261.2 |
x11.conf rule |
D! (boot-only) |
D! (boot-only) |
D |
| debhelper | 13.11.4 | 13.14.1ubuntu5 | 14.3 |
| postinst guard | || true |
|| true |
none |
/run/tmpfiles.d/x11.conf |
absent | present | absent |
/mnt/wslg/runtime-dir |
exists | exists | exists |
| PID 1 | init |
systemd |
init |
- The
!flag.D!marks a rule boot-only;systemd-tmpfiles --createskips it unless--bootis given, and the postinst does not pass--boot. Upstream systemd has since dropped the!. The currentmainreadsD /tmp/.X11-unix 1777 root root 1h. || true. debhelper 13.x appended it to the generated call; 14.3 does not. Ubuntu's own postinst carries a hand-written comment above its call: "Ignore if this fails, because e.g. %b will fail on WSL."- WSL's mitigation: The part this report is about.
The specific WSL-side finding
I don't see this occurring on a non-WSL linux machine, since it is tied into how WSLg works. (I quickly looked at the code and I think I may have found part of the problem, but I could be wrong.)
/run/tmpfiles.d/x11.conf contains exactly:
# Note: This file is generated by WSL to prevent systemd-tmpfiles from removing /tmp/.X11-unix during boot.
Being empty of rules, it shadows /usr/lib/tmpfiles.d/x11.conf entirely by tmpfiles.d(5) precedence and neutralises the problem completely. It is present on the Ubuntu instance (systemd enabled) and absent on Kali and Debian (both init), where /run/tmpfiles.d/ does not exist at all.
The obvious explanation, that a precondition isn't met on those distros, does not hold. /mnt/wslg/runtime-dir exists on all three, and GUI apps are working on all three (DISPLAY=:0, live X0 socket). So both conditions WSL tests are already true where the file is missing.
Reading src/linux/init/init.cpp at 4bfbaca, the write appears as:
if (enableGuiApps && access("/mnt/wslg/runtime-dir", F_OK) == 0)
{
THROW_LAST_ERROR_IF(UtilMkdirPath("/run/tmpfiles.d", 0755) < 0);
const std::string tmpFilesConfig =
"# Note: This file is generated by WSL to prevent systemd-tmpfiles from removing /tmp/.X11-unix during boot.\n";
THROW_LAST_ERROR_IF(WriteToFile("/run/tmpfiles.d/x11.conf", tmpFilesConfig.c_str()) < 0);Which sits inside GenerateSystemdUnits(): a function that would not be expected to run when systemd is not the init system. That would explain the observed behaviour, though I may be misreading the call graph; the empirical results above stand regardless of that detail.
Suggested fix
I have only given a cursory glance at WSL to fix my own local distro, however I would advise that you write /run/tmpfiles.d/x11.conf on every WSLg-enabled distro, not only those booting systemd. The guard conditions already written (enableGuiApps + /mnt/wslg/runtime-dir) appear to express exactly the right intent; only the placement excludes the affected case. The file is inert on a system that never runs systemd-tmpfiles at boot, so writing it unconditionally should carry no cost.
A distro not booting systemd can still have the systemd package installed, and its maintainer scripts still run systemd-tmpfiles at package-configure time, which is the case I think this misses.
Alternatively, mounting /tmp/.X11-unix with mode 1777 would satisfy the rule, instead of violating it, and would additionally address the long-standing _XSERVTransmkdir: Mode of /tmp/.X11-unix should be set to 1777 warnings (#11943).
Workaround
What I did to 'fix' it on my local distro so that I could update my wsl -d kali-linux:
Shadow the vendor rule from /etc, which takes precedence over /usr/lib and survives upgrades. The vendor file is not a dpkg conffile and is restored on every systemd upgrade, so editing it is ineffective:
sudo tee /etc/tmpfiles.d/x11.conf >/dev/null <<'EOF'
D /tmp/.ICE-unix 1777 root root 1h
D /tmp/.XIM-unix 1777 root root 1h
D /tmp/.font-unix 1777 root root 1h
r! /tmp/.X[0-9]*-lock
x /tmp/.X[0-9]*-lock
EOF
sudo dpkg --configure -aRelated
- /tmp/.X11-unix is being mounted read-only #9303 -
/tmp/.X11-unixmounted read-only (closedbydesign) - _XSERVTransmkdir: Mode of /tmp/.X11-unix should be set to 1777 #11943 - mode of
/tmp/.X11-unixshould be 1777 (closed as duplicate) - Discussion A modest proposal in re systemd support, WSLg, and how to support the latter in the former #8908 - systemd support and WSLg
- The same
fchmod()failure reported independently in other ecosystems, each worked around locally:
fchmod() of /tmp/.X11-unix failed: Read-only file system nix-community/NixOS-WSL#269, systemd default tmpfiles removes /tmp/.X11-unix/X0 nix-community/NixOS-WSL#114, WSL integration OpenRC/openrc#871
Side note
I do not commonly submit bug reports, so I am sorry if this isn't clear enough. Hopefully I provided enough information to get to the root of the problem.
Activity
github-actions commentedon Aug 31, 2026
Logs are required for review from WSL team
If this a feature request, please reply with '/feature'. If this is a question, reply with '/question'.
Otherwise, please attach logs by following the instructions below, your issue will not be reviewed unless they are added. These logs will help us understand what is going on in your machine.
How to collect WSL logs
Download and execute collect-wsl-logs.ps1 in an administrative powershell prompt:
The script will output the path of the log file once done.
If this is a networking issue, please use
.\collect-wsl-logs.ps1 -LogProfile networkinginstead, following the instructions in Collect WSL logs for networking issuesOnce completed please upload the output files to this GitHub issue.
See Collect WSL logs (recommended method).
If you choose to email these logs instead of attaching them to the bug, please send them to [email protected] with the GitHub issue number in the subject, and include a link to your GitHub issue comment in the message body, and reply with '/emailed-logs'.
Eman0202 commentedon Aug 31, 2026
/emailed-logs
Logs sent to [email protected] with issue #41488 in the subject line.
Flagging one thing so nobody spends time hunting through the trace: the failure
happens entirely inside the Linux guest, in the systemd package postinst when it
calls
systemd-tmpfiles, so it does not appear in the Windows side ETL. Ireproduced it inside the capture window, but there is nothing there to find.
The single command repro in the issue body triggers it directly on any WSLg
distro that is not booting systemd:
which exits 73 with
fchmod() of /tmp/.X11-unix failed: Read-only file system.(I do not feel comfortable sharing a file that contains my windows username in a public repo)
github-actions commentedon Aug 31, 2026
Diagnostic information