microsoft / microsoft/WSL

[WSL 2.9 regression] Rootless Docker/Podman cannot start any container — standard /sys/fs/cgroup/user.slice path missing after cgroup hierarchy moved under /wsl-user/distro-N/

Open
#41,492 14 comments 1 reaction 0 assignees View on GitHub
emailed-logs external wsl2
Dominant language
C++
Stars
33.7k
Forks
1.8k
Avg merge
3d 17h
Merged PRs (30d)
116

Description

## Windows Version

`10.0.26300.9278`

## WSL Version

`2.9.9.0` (Pre-release channel)

Full `wsl --version`:

```
WSL version: 2.9.9.0
Kernel version: 6.18.40.1-1
WSLg version: 1.0.79
MSRDC version: 1.2.7214
Direct3D version: 1.611.1-81528511
DXCore version: 10.0.26100.1-240331-1435.ge-release
Windows version: 10.0.26300.9278
```

## Are you using WSL 1 or WSL 2?

- [x] WSL 2

## Kernel Version

`6.18.40.1-microsoft-standard-WSL2`

## Distro Version

Fedora Linux 44 (WSL). Also reproduced on Fedora Linux 42 (WSL) after upgrading WSL to 2.9.x.

## Other Software

Docker CE **rootless** mode (`dockerd-rootless`), running as a `systemctl --user` service:

```
Docker version 29.7.2, build a7dcaa6
runc version 1.4.3
rootlesskit version 3.0.2
containerd containerd v2.3.4
```

## Repro Steps

Rootless Docker (and, by the same root cause, rootless Podman) can no longer start **any** container after updating WSL to **2.9.x**. The identical setup works on WSL **2.7.x**.

1. On WSL **2.9.9** with systemd enabled, run rootless Docker as a user service (standard `dockerd-rootless-setuptool.sh install`).
2. Attempt to run any container as the (non-root) user:

```console
$ docker run --rm hello-world
docker: Error response from daemon: open /sys/fs/cgroup/user.slice/user-1000.slice/cgroup.controllers: no such file or directory
```

Setting a CPU limit fails the same way (the daemon reports no CFS support):

```console
$ docker run --rm --cpus=1.0 hello-world
docker: Error response from daemon: NanoCPUs can not be set, as your kernel does not support CPU CFS scheduler or the cgroup is not mounted
```

### Root cause (isolated)

WSL 2.9 relocated the entire cgroup v2 hierarchy under a per-distro root (`/wsl-user/distro-/…`), leaving the standard top-level `/sys/fs/cgroup/user.slice/…` path that rootless Docker/`rootlesskit` expect **absent**:

```console
# The path the rootless daemon looks for — MISSING:
$ ls /sys/fs/cgroup/user.slice/user-1000.slice/cgroup.controllers
ls: cannot access '/sys/fs/cgroup/user.slice/user-1000.slice/cgroup.controllers': No such file or directory

# Where the cgroups actually live under 2.9:
$ cut -d: -f3 /proc/self/cgroup
/wsl-user/distro-282/non-systemd

$ systemctl show user@1000.service -p ControlGroup --value
/wsl-user/distro-282/systemd/user.slice/user-1000.slice/user@1000.service
```

The following rule out the kernel and Docker as the cause:

- **Kernel supports CFS bandwidth** and the interface exists (so this is not a missing kernel config):

```console
$ zcat /proc/config.gz | grep CFS_BANDWIDTH
CONFIG_CFS_BANDWIDTH=y
$ ls /sys/fs/cgroup/wsl-user/distro-282/systemd/user.slice/user-1000.slice/user@1000.service/cpu.max
.../cpu.max # present
```

- **Rootful (system) Docker works**, including CPU limits — isolating the fault to the rootless / systemd-user cgroup handling under WSL 2.9:

```console
$ sudo docker run --rm --cpus=1.0 hello-world # succeeds
```

- I also observed **more than one distro cgroup root** appearing across sessions (`/wsl-user/distro-282/…` and `/wsl-user/distro-285/…`), which suggests the per-distro cgroup subtree and controller delegation are not being set up consistently.

## Expected Behavior

Rootless containers start and per-container resource limits (`--cpus`, etc.) work — the behavior on WSL 2.7.x. The standard cgroup v2 delegation (`/sys/fs/cgroup/user.slice/user-.slice/…` with the `cpu`/`memory` controllers delegated to `user@.service`) should be present so that `rootlesskit`/`dockerd` and `podman` operate normally.

## Actual Behavior

After updating to WSL 2.9.x, rootless Docker cannot start any container. `rootlesskit`/`dockerd` fail resolving `/sys/fs/cgroup/user.slice/user-1000.slice/cgroup.controllers` (which no longer exists because the hierarchy was moved under `/wsl-user/distro-/…`), and the daemon reports no CFS/CPU-quota support even though the kernel provides it. This is a regression from WSL 2.7.x, where the same rootless setup works. Related prior reports of rootless-container/systemd-user cgroup breakage on the WSL tracker: #13053, #13143.

## Diagnostic Logs

Key values are inline above (`wsl --version`, kernel, `/proc/self/cgroup`, the missing path, and `CONFIG_CFS_BANDWIDTH`). I can attach a full `collect-wsl-logs.ps1` bundle and `strace` of the failing `dockerd`/`rootlesskit` on request.

Contributor guide

Open the contributing guide

Research direction

Start by reproducing the rootless Docker failure on WSL 2.9.9 and compare `/proc/self/cgroup`, the `/sys/fs/cgroup` paths, and controller delegation with WSL 2.7.x. Use the inline `wsl --version` and cgroup diagnostics, and collect `collect-wsl-logs.ps1` output if needed. Done means rootless Docker and Podman can start containers with resource limits through the standard user cgroup paths.

Written by the indexing model from the issue text.

Assessment

Tech stack
docker, linux
Domain
infrastructure, operating-systems
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.