Why WSL Didn't Support systemd at First, and How It Works Now
WSL distros ran without systemd for years, breaking software expecting PID 1 init. Here is why that gap existed and how it was architecturally closed.
For years after WSL2’s release, running systemctl inside a WSL distro produced an error rather than managing services — a gap that broke any software expecting systemd to be running as PID 1, until specific WSL platform changes closed it.
Why systemd wasn’t there from the start
WSL distros originally launched directly into a shell or specified command, without running a traditional Linux init system as PID 1 at all — systemd itself makes assumptions about controlling cgroups, mount namespaces, and the boot sequence in ways that conflicted with how WSL2’s lightweight VM launched its Linux environment, which was optimized for fast startup rather than replicating a full traditional Linux boot sequence.
What broke, specifically, without systemd
Any software depending on systemctl to start, stop, or check the status of a background service — Docker’s daemon on some configurations, various database services, and other software packaged assuming a systemd-based distro — either failed outright or required manual, non-standard workarounds to start services without systemd’s involvement at all.
What Microsoft and Canonical actually changed
Starting with updates in September 2022, Microsoft (working with Canonical) modified WSL2’s launch sequence to properly initialize systemd as an actual PID 1 process inside the Linux environment, correctly integrated with WSL2’s specific cgroup and namespace setup — a genuine architectural change to how the WSL2 environment boots, not just a compatibility shim layered on top.
How to actually enable it
/etc/wsl.conf
[boot]
systemd=true
Systemd support is opt-in per distro via this configuration file, requiring a full distro restart (wsl --shutdown followed by relaunching) to take effect — it’s not automatically enabled for existing distro installations upgrading to a newer WSL version.
Why opt-in, rather than enabled by default
Enabling systemd changes the distro’s boot behavior in ways that could affect distros specifically configured to work without it — making it an explicit, deliberate choice avoids silently changing behavior for existing setups that never expected or needed systemd running.
What actually works once it’s enabled
With systemd running as PID 1, standard systemctl start/stop/enable commands work as they would on a bare-metal or conventionally-virtualized Linux system — meaningfully improving compatibility with software distributed assuming a standard systemd-managed distro, including Docker’s own systemd-based service management in some configurations.
Why this gap mattered enough to justify the architectural work
systemd has become close to universal across mainstream Linux distros over the past decade — software packaged with the reasonable assumption that systemd is available and running increasingly just didn’t work correctly under WSL without it, making this a meaningful compatibility gap rather than a minor missing feature, and explaining why closing it took genuine collaborative engineering between Microsoft and Canonical rather than a simple configuration flag.
The process-tree change
The architectural detail is subtler than “systemd becomes the WSL VM.” WSL still has its own host-side service and utility-VM lifecycle. Inside an enabled distribution, Microsoft changed the WSL init path so systemd can run as PID 1 while the WSL-provided init process remains involved beneath it in the integration. That arrangement preserves Windows interop, filesystem mounts, networking integration, and orderly shutdown while giving Linux packages the PID 1 and cgroup environment they expect.
Because PID 1 has special signal and orphan-reaping behavior, substituting a normal user process was never equivalent. systemd brings unit dependency ordering, socket and timer activation, journald, user managers, and cgroup-based service tracking. It also means a broken unit, generator, or mount can now delay the distribution boot path in ways that did not exist when WSL used only its minimal init.
Configuration and verification
Microsoft documents the distribution-local setting:
[boot]
systemd=true
After changing /etc/wsl.conf, stop the WSL environment from Windows with wsl.exe --shutdown, start the distribution again, and verify rather than assume:
ps -p 1 -o pid,comm,args
systemctl is-system-running
systemctl --failed
journalctl -b -p warning
is-system-running can report degraded when one optional unit failed even though the shell works. Diagnose the named unit and its journal; do not repeatedly toggle the feature or delete the journal. A distribution also needs a current systemd package and a WSL version that supports the integration. Enterprise policy or an older inbox WSL can explain why identical distro files behave differently on two Windows machines.
Service lifetime is not machine lifetime
systemd can supervise a daemon while the distribution is active, but it does not turn a laptop environment into an always-on host. Windows shutdown, wsl --shutdown, updates, user actions, or WSL resource policy can terminate the environment. Services must handle SIGTERM, flush data, and recover cleanly. Production databases still need backups and an availability design outside a developer workstation.
Compatibility boundaries
Hardware-facing units may remain inappropriate because WSL virtualizes or omits the expected device. Firewall behavior spans both Linux and Windows layers. Time, DNS, and network interfaces are influenced by WSL integration. Conversely, container tools and packages that simply require systemd unit management can now use their upstream service definitions with fewer WSL-specific patches.
The correct test is workload-specific: confirm boot, shutdown, journal persistence, sockets, timers, user services, and failure recovery. Do not use the presence of systemctl alone as proof that a service will survive the surrounding Windows lifecycle.
Primary references: Microsoft Learn systemd guide, Microsoft’s engineering announcement, systemd PID 1 documentation.
Recovery when PID 1 breaks
Before enabling the feature on an important distro, export data and ensure a second distro starts. If boot fails after a unit or mount change, use the current Microsoft-supported recovery or safe-mode path, repair the smallest configuration error, then shut WSL down cleanly and retest. Avoid editing ext4.vhdx directly from Windows or unregistering the distro. Capture wsl --version, Windows build, /etc/wsl.conf, failed units, and the boot journal in the incident record; those facts distinguish a WSL integration regression from an ordinary Linux unit failure.
Related:
Sources: