[BUG] Claude Desktop SSH Remote: server binary never executes despite successful auth (macOS → Windows/WSL2)

Resolved 💬 3 comments Opened Apr 5, 2026 by omid-web Closed May 15, 2026

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

  1. Set up Windows 11 with OpenSSH server, DefaultShell set to WSL2 bash
  2. Configure SSH key auth with a username containing a space
  3. Confirm terminal SSH works: ssh user@host "echo OK"
  4. In Claude Desktop → Code tab → Add SSH connection
  5. Set SSH Host to the config alias or user@host
  6. 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 ssh2 exec failure pattern
  • #32734 — testSSHConnection succeeds but getSSHGitInfo fails (closed as dup of #25933)
  • #27165 — Windows SSH connected but stuck

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗