[BUG] Claude Desktop SSH Remote: server binary never executes despite successful auth (macOS → Windows/WSL2)
Bug Description
Claude Desktop's SSH remote feature fails to launch the remote server binary, even though SSH authentication succeeds and all components work independently via terminal SSH. The ssh2 library establishes a connection but the exec/shell channel never runs the server command.
Environment
| Component | Details |
|-----------|---------|
| Client OS | macOS (Darwin 25.4.0) |
| Client App | Claude Desktop (latest), Claude Code 2.1.x |
| Remote OS | Windows 11, OpenSSH_for_Windows_9.5 |
| Remote Shell | WSL2 bash (Ubuntu) set as DefaultShell |
| Network | VPN overlay (ZeroTier), port 22 (standard) |
| Auth Method | RSA key, no passphrase, pubkey auth |
| SSH Username | Contains a space (e.g., First Last) |
Symptoms
Two distinct errors depending on how the SSH host is configured:
| Configuration | Error |
|--------------|-------|
| SSH config alias | "Timed out while waiting for handshake" |
| Explicit First Last@<ip> | "RPC call to server.ping timed out" / "Timeout waiting for remote server socket" |
The second form is progress — SSH auth succeeds, but the remote server never starts.
Evidence That Server Never Launches
# After every Claude Desktop connection attempt:
$ stat ~/.claude/remote/remote-server.log
Size: 0 # empty — no startup output, no errors
$ ls ~/.claude/remote/rpc.sock
ls: cannot access: No such file or directory # socket never created
$ ps aux | grep claude
# no server process running
Evidence That Everything Works Independently
# Terminal SSH connects instantly
$ ssh myhost "echo OK"
OK
# Remote server binary runs and creates socket
$ ssh myhost '~/.claude/remote/server serve --stdio'
Claude remote server listening on /home/user/.claude/remote/rpc.sock
# Server binary is valid
$ ssh myhost 'file ~/.claude/remote/server'
ELF 64-bit LSB executable, x86-64, statically linked, Go BuildID=...
# Claude CLI is installed on remote
$ ssh myhost '~/.local/bin/claude --version'
2.1.91 (Claude Code)
# SSH verbose output confirms full auth chain
$ ssh -v myhost "echo OK"
debug1: kex: algorithm: ecdh-sha2-nistp256 # KEX ✓
debug1: Host '<ip>' is known # Host key ✓
debug1: Accepted publickey # Auth ✓
OK # Session ✓
Troubleshooting Attempted
| # | Hypothesis | Action | Result |
|---|-----------|--------|--------|
| 1 | SSH compression breaks ssh2 | Set Compression no for this host | No change |
| 2 | SSH config alias causes issues | Used explicit user@host in Claude Desktop UI | Error changed from handshake timeout to RPC timeout (partial progress) |
| 3 | KEX algorithm incompatibility | Verified: ecdh-sha2-nistp256, ssh-ed25519, aes128-gcm — all standard | Ruled out |
| 4 | ~/.local/bin not in PATH for non-interactive SSH | Added PATH export before .bashrc interactive guard | PATH fixed, but no change to Desktop error |
| 5 | Server binary wrong architecture | Verified: ELF 64-bit x86-64, runs successfully | Ruled out |
| 6 | Disk/permissions issue | Verified disk space, correct permissions | Ruled out |
| 7 | Stale socket blocking new one | Checked: no socket file exists | Ruled out |
Root Cause Analysis
The failure occurs in Claude Desktop's Node.js ssh2 library at the command execution phase — after successful authentication but before the remote server binary runs.
SSH Connection Flow:
1. TCP connect ✓ (confirmed via ping + ssh)
2. Protocol negotiation ✓ (SSH-2.0 both sides)
3. Key exchange (KEX) ✓ (ecdh-sha2-nistp256)
4. Host key verification ✓ (ed25519, known_hosts match)
5. User authentication ✓ (publickey accepted)
6. Channel/exec ✗ ← FAILURE HERE
Server binary never executes
Log file: 0 bytes
Socket: never created
The same binary, same path, same user, same key — all work when invoked via system OpenSSH. The ssh2 library's exec or shell channel silently fails to run the command.
Contributing factor: The SSH username contains a space. The ssh2 library may not properly handle this in command construction. Evidence: switching from config alias to explicit user@host changed the error behavior.
Steps to Reproduce
- Set up Windows 11 with OpenSSH server, DefaultShell set to WSL2 bash
- Configure SSH key auth with a username containing a space
- Confirm terminal SSH works:
ssh user@host "echo OK" - In Claude Desktop → Code tab → Add SSH connection
- Set SSH Host to the config alias or
user@host - Attempt to connect → "Timed out while waiting for handshake" or "RPC call to server.ping timed out"
Expected Behavior
Claude Desktop should execute ~/.claude/remote/server serve on the remote machine after successful SSH authentication, creating the Unix socket and establishing the RPC connection.
Related Issues
- #35073 — Same handshake timeout, Windows → Linux, identical
ssh2exec failure pattern - #32734 —
testSSHConnectionsucceeds butgetSSHGitInfofails (closed as dup of #25933) - #27165 — Windows SSH connected but stuck
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗