Where does the bug appear (feature/product)?
Somewhere else…
Describe the Bug
SSH agent forwarding into Docker devcontainers on Windows hangs indefinitely. Running ssh-add -l inside the container never returns — it blocks forever with no output and no error.
The host-side SSH agent works correctly: keys are loaded (ssh-add -l works in PowerShell), and SSH connections succeed from the host. The Cursor logs confirm the forwarding is detected and set up:
Windows detected: using OpenSSH agent at \\.\pipe\openssh-ssh-agent
Forwarding SSH agent \\.\pipe\openssh-ssh-agent socket
[ssh_auth_socket] created socket server in container and bound forwarder to it
====socketForward=success====
On the first client connection from inside the container, the log shows:
handleClient stderr: Connection established 0
Then complete silence. No error, no data relayed, no timeout. The forwarder process is frozen.
Root cause: The forwarder process that bridges the container socket to the host’s SSH agent has a function (createLocalSocketConnection) that, before connecting to the local socket, passes the path to another function (parseWindowsAssuanSocket) which calls fs.readFileSync() on it. This is intended for GPG Assuan socket files (regular text files containing connection info), but on Windows the SSH agent path is \\.\pipe\openssh-ssh-agent — a named pipe, not a regular file. Calling readFileSync on a named pipe opens a connection and blocks waiting for the pipe server to send data. Since the SSH agent expects the client to speak first, this deadlocks. Because readFileSync is synchronous, it freezes the entire Node.js event loop of the forwarder, and no data ever flows through.
The fix is to skip the Assuan socket file parsing for paths that are Windows named pipes (matching \\.\pipe\*) and go straight to net.createConnection(), which handles named pipes correctly.
After applying this fix locally, SSH agent forwarding works perfectly — ssh-add -l shows the host keys and SSH connections succeed from inside the container.
Steps to Reproduce
- Use Windows 11 with the built-in OpenSSH agent service running (
Set-Service ssh-agent -StartupType Automatic; Start-Service ssh-agent) - Load keys into the agent (e.g. via KeePassXC or
ssh-add) - Verify
ssh-add -lworks in PowerShell on the host - Open a Docker devcontainer in Cursor
- Open a terminal in the container
- Run
ssh-add -l - Result: Hangs forever (no output, no error, no timeout)
Standalone reproduction of the underlying issue (standard Node.js, no Cursor code — run on any Windows machine with the OpenSSH agent service running):
node -e "require('fs').readFileSync('//./pipe/openssh-ssh-agent')"
This hangs forever, demonstrating that fs.readFileSync deadlocks on the SSH agent named pipe.
Expected Behavior
ssh-add -l inside the devcontainer should list keys from the host’s SSH agent. SSH connections from the container should authenticate using the forwarded agent.
Operating System
Windows 10/11
Version Information
Version: 2.4.31 (user setup)
VSCode Version: 1.105.1
Commit: 3578107fdf149b00059ddad37048220e41681000
Date: 2026-02-08T07:42:24.999Z
Build Type: Stable
Release Track: Default
Electron: 39.2.7
Chromium: 142.0.7444.235
Node.js: 22.21.1
V8: 14.2.231.21-electron.0
OS: Windows_NT x64 10.0.26200
Extension: anysphere.remote-containers 1.0.32
Docker Desktop: latest (WSL2 backend)
OpenSSH: OpenSSH_for_Windows_10.0p2
SSH agent: Windows OpenSSH agent service
Additional Information
This bug was debugged with the help of Claude (Anthropic) running via Claude Code on the Windows host. The process was:
- Verified the Windows OpenSSH agent worked on the host (
ssh-add -lshowed keys, SSH to remote server succeeded). - Inspected the container-side relay process — it was running and accepting connections, but returning no data.
- Checked the Cursor Dev Containers log at
%APPDATA%\Cursor\logs\...\exthost\anysphere.remote-containers\Remote - Dev Containers.log, which showed the forwarder spawning successfully with\\.\pipe\openssh-ssh-agentas the local socket argument. - Claude read the locally-installed file
%USERPROFILE%\.cursor\extensions\anysphere.remote-containers-1.0.32\dist\scripts\forwarder.json my machine to trace the code path. The function names referenced in this report (createLocalSocketConnection,parseWindowsAssuanSocket) were identified by Claude from this shipped JavaScript file. No decompilation or reverse engineering tools were used — the file is distributed as readable (minified) JavaScript. - Claude identified that
parseWindowsAssuanSocketcallsfs.readFileSyncon whatever socket path it receives, and hypothesized this would deadlock on a Windows named pipe. - Confirmed the hypothesis with the standalone Node.js reproduction above —
fs.readFileSyncon the SSH agent named pipe hangs indefinitely. - Patched the local extension file to skip the Assuan check for named pipe paths, reloaded Cursor, and verified
ssh-add -land SSH connections work from inside the container.
Does this stop you from using Cursor
No - Cursor works, but with this issue