-
Notifications
You must be signed in to change notification settings - Fork 2k
Description
Description
Running docker exec
against a container running on the WSL Docker daemon returns no output.
Adding -i
fixes the problem when running in an interactive PowerShell session.
However, when running in an environment with no stdin (like an Azure DevOps pipeline), even -i
does not fix the output.
Related issues/PRs:
- No output when running hello-world without -i over WSL 2 Docker context #3586
- /cli/command/container/hijack.go: fix tcp half-closed connection unreliability in WSL #4548
- net/http/httputil: ReverseProxy doesn't support TCP half-close when HTTP is upgraded golang/go#35892 (comment)
- https://go-review.googlesource.com/c/go/+/637939
Reproduce
Using Windows Server 2022 with Docker Engine (not Desktop) installed, but should reproduce on any modern Windows OS with a Docker client.
- Install Docker in WSL and expose a TCP port.
# In WSL Bash curl -fsSL https://get.docker.com -o get-docker.sh ./get-docker.sh mkdir -p /etc/systemd/system/docker.service.d cat <<EOF > /etc/systemd/system/docker.service.d/docker.conf [Service] ExecStart= ExecStart=/usr/bin/dockerd EOF cat <<EOF > /etc/docker/daemon.json { "hosts": ["unix:///var/run/docker.sock", "tcp://0.0.0.0:2375"], "tls": false } EOF systemctl daemon-reload systemctl restart docker
- In the Windows Docker client (running via PowerShell), add a context for WSL using the TCP port.
# In PowerShell (all remaining steps as well) docker context create wsl --docker "host=tcp://localhost:2375" docker context use wsl
- Create a Linux container in WSL Docker using the Windows Docker client.
docker -c wsl run --rm -d --name linux-container mcr.microsoft.com/azurelinux/base/core:3.0 tail -f /dev/null
- Create a Windows container as well.
docker -c default run --rm -d --name windows-container mcr.microsoft.com/windows/nanoserver:ltsc2022 cmd /c ping -t localhost > NUL
- Run a command in the Linux container (these will return no output).
docker -c wsl exec linux-container cat /etc/os-release $null | docker -c wsl exec linux-container cat /etc/os-release $null | docker -c wsl exec -i linux-container cat /etc/os-release
- Run a command in the Linux container (this will return output).
docker -c wsl exec -i linux-container cat /etc/os-release
- Run a command in the Windows container (these will return output).
docker -c default exec windows-container ping docker -c default exec -i windows-container ping $null | docker -c default exec windows-container ping $null | docker -c default exec -i windows-container ping
Expected behavior
The commands in step 5 which run in the Linux container should all return output, but they do not. Only the command in step 6 works, but it relies on having an active stdin (not the case in CI like Azure DevOps pipelines, replicated by the $null | ...
commands).
docker version
$ docker -c wsl version
Client:
Version: 28.3.2
API version: 1.51
Go version: go1.24.5
Git commit: 578ccf6
Built: Wed Jul 9 16:12:31 2025
OS/Arch: windows/amd64
Context: wsl
Server: Docker Engine - Community
Engine:
Version: 28.3.2
API version: 1.51 (minimum version 1.24)
Go version: go1.24.5
Git commit: e77ff99
Built: Wed Jul 9 16:13:45 2025
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.7.27
GitCommit: 05044ec0a9a75232cad458027ca83437aae3f4da
runc:
Version: 1.2.5
GitCommit: v1.2.5-0-g59923ef
docker-init:
Version: 0.19.0
GitCommit: de40ad0
$ docker -c default version
Client:
Version: 28.3.2
API version: 1.51
Go version: go1.24.5
Git commit: 578ccf6
Built: Wed Jul 9 16:12:31 2025
OS/Arch: windows/amd64
Context: default
Server: Docker Engine - Community
Engine:
Version: 28.3.2
API version: 1.51 (minimum version 1.24)
Go version: go1.24.5
Git commit: e77ff99
Built: Wed Jul 9 15:41:13 2025
OS/Arch: windows/amd64
Experimental: false
docker info
$ docker -c wsl info
Client:
Version: 28.3.2
Context: wsl
Debug Mode: false
Server:
Containers: 2
Running: 2
Paused: 0
Stopped: 0
Images: 5
Server Version: 28.3.2
Storage Driver: overlay2
Backing Filesystem: extfs
Supports d_type: true
Using metacopy: false
Native Overlay Diff: true
userxattr: false
Logging Driver: json-file
Cgroup Driver: systemd
Cgroup Version: 2
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local splunk syslog
CDI spec directories:
/etc/cdi
/var/run/cdi
Swarm: inactive
Runtimes: io.containerd.runc.v2 runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 05044ec0a9a75232cad458027ca83437aae3f4da
runc version: v1.2.5-0-g59923ef
init version: de40ad0
Security Options:
seccomp
Profile: builtin
cgroupns
Kernel Version: 6.6.87.2-microsoft-standard-WSL2
Operating System: Ubuntu 24.04.2 LTS
OSType: linux
Architecture: x86_64
CPUs: 16
Total Memory: 62.8GiB
Name: mark-test-vm2
ID: c8957280-19af-4e36-86d7-fac6425f4b5b
Docker Root Dir: /var/lib/docker
Debug Mode: false
Experimental: false
Insecure Registries:
::1/128
127.0.0.0/8
Live Restore Enabled: false
[DEPRECATION NOTICE]: API is accessible on http://0.0.0.0:2375 without encryption.
Access to the remote API is equivalent to root access on the host. Refer
to the 'Docker daemon attack surface' section in the documentation for
more information: https://docs.docker.com/go/attack-surface/
In future versions this will be a hard failure preventing the daemon from starting! Learn more at: https://docs.docker.com/go/api-security/
$ docker -c default info
Client:
Version: 28.3.2
Context: default
Debug Mode: false
Server:
Containers: 1
Running: 1
Paused: 0
Stopped: 0
Images: 3
Server Version: 28.3.2
Storage Driver: windowsfilter
Windows:
Logging Driver: json-file
Plugins:
Volume: local
Network: ics internal l2bridge l2tunnel nat null overlay private transparent
Log: awslogs etwlogs fluentd gcplogs gelf json-file local splunk syslog
CDI spec directories:
/etc/cdi
/var/run/cdi
Swarm: inactive
Default Isolation: process
Kernel Version: 10.0 20348 (20348.1.amd64fre.fe_release.210507-1500)
Operating System: Microsoft Windows Server Version 21H2 (OS Build 20348.3932)
OSType: windows
Architecture: x86_64
CPUs: 16
Total Memory: 128GiB
Name: mark-test-vm2
ID: 27828f3f-c78c-4bc9-b7f3-f2fbeee7f3ae
Docker Root Dir: C:\ProgramData\docker
Debug Mode: false
Experimental: false
Insecure Registries:
::1/128
127.0.0.0/8
Live Restore Enabled: false
Product License: Community Engine
Additional Info
Docker client is on Windows, Docker daemon is on WSL 2 (Ubuntu). Tested via Windows Sever 2022 running in Azure.
If you add the debug flag -D
to the commands you can see some extra output which could help with troubleshooting:
$null | docker -D -c default exec -i windows-container ping
(...output...)
time="2025-07-29T18:40:58Z" level=debug msg="[hijack] End of stdin"
time="2025-07-29T18:40:58Z" level=debug msg="[hijack] End of stdout"
docker -D -c wsl exec -i linux-container cat /etc/os-release
(...output...)
time="2025-07-29T18:43:24Z" level=debug msg="[hijack] End of stdout"
$null | docker -D -c wsl exec -i linux-container cat /etc/os-release
time="2025-07-29T18:42:17Z" level=debug msg="[hijack] End of stdin"
time="2025-07-29T18:42:17Z" level=debug msg="[hijack] End of stdout"