microsoft / microsoft/WSL

`wslc` unable to bind mount WSL host paths, blocking 'docker-in-docker' scenarios

Open
#40,957 9 comments 1 reaction 1 assignee Claimed by @craigloewen-msft View on GitHub
feature wslc
Dominant language
C++
Stars
33.7k
Forks
1.8k
Avg merge
3d 17h
Merged PRs (30d)
116

Description

### Windows Version

Microsoft Windows [Version 10.0.26200.8655]

### WSL Version

2.9.3.0

### Are you using WSL 1 or WSL 2?

- [x] WSL 2
- [ ] WSL 1

### Kernel Version

6.18.35.2-1

### Distro Version

N/A — using `wslc` (WSL Container); no WSL distro is involved.

### Other Software

- Visual Studio Code with the Dev Containers extension
- A devcontainer using the `ghcr.io/devcontainers/features/docker-in-docker:2` feature which adds `-v /var/run/docker.sock:/var/run/docker-host.sock` to the container run args

### Repro Steps

1. Create a devcontainer that includes the `docker-in-docker` feature (or any configuration that bind-mounts `/var/run/docker.sock`):

```json
"features": {
"ghcr.io/devcontainers/features/docker-in-docker:2": {
"version": "latest"
}
}
```

2. Open the folder in a Dev Container via VS Code using the `wslc` backend. The devcontainer tooling generates a `wslc run` command including:

```
-v /var/run/docker.sock:/var/run/docker-host.sock
```

3. Observe the failure.

Alternatively, reproduce directly:

```
wslc run -v /var/run/docker.sock:/var/run/docker-host.sock echo test
```

### Expected Behavior

The wslc VM runs `dockerd` (with `--containerd /run/containerd/containerd.sock`), so both `/var/run/docker.sock` and `/run/containerd/containerd.sock` exist and are presumably live inside the VM. A bind mount of either socket path into a container should succeed, consistent with how `docker run -v /var/run/docker.sock:...` behaves on Linux.

### Actual Behavior

The container fails to start with the following error:

```
failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: error mounting "/mnt/{f691e24a-17af-4f59-b009-9779dccee8e7}" to rootfs at "/var/run/docker-host.sock": mount src=/mnt/{f691e24a-17af-4f59-b009-9779dccee8e7}, dst=/var/run/docker-host.sock, dstFd=/proc/thread-self/fd/41, flags=MS_BIND|MS_REC: not a directory: unknown: Are you trying to mount a directory onto a file (or vice-versa)? Check if the specified host path exists and is the expected type
Error code: E_INVALIDARG
```

Claude suggests the following root cause:
>`WSLCContainer.cpp` resolves all `-v` source paths using `std::filesystem::canonical` treating them as Windows filesystem paths. When given `/var/run/docker.sock`, that path does not exist on Windows, so the resolution falls back to creating a fresh GUID-based VHD and mounting the parent directory at `/mnt/{GUID}`. That mount point is a directory, not a socket file, so runc rejects the bind mount.

>The same failure occurs with `/run/containerd/containerd.sock`. Both sockets are live in the VM but are unreachable through the `-v` flag because the source-path resolver is Windows-only.

>The GUID in the error message is newly allocated per-run (via `CoCreateGuid`), so the path will differ between attempts.

### Diagnostic Logs

N/A — the error is fully reproduced from the terminal output above.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.