Skip to content

Coder Runtime: ssh2-proxy-socket Premature close on Windows with self-hosted Coder deployment #3110

@mathomas95

Description

@mathomas95

Coder Runtime: ssh2-proxy-socket Premature close on Windows with self-hosted Coder deployment

Description

The Coder Runtime fails to establish an SSH connection to a self-hosted Coder workspace on Windows. Every connection attempt results in ERR_STREAM_PREMATURE_CLOSE on the ssh2-proxy-socket, immediately going into backoff and eventually timing out.

Normal SSH via coder ssh <workspace> works perfectly from the same machine. The SSH Runtime workaround (using coder config-ssh host aliases with system OpenSSH) also works fine. The issue is isolated to Mux's internal Node.js ssh2 library when used with the Coder Runtime's ProxyCommand on Windows.

Environment

  • Mux version: (latest stable as of 2026-04-01)
  • OS: Windows 10/11
  • Coder server: v2.31.6 (self-hosted on NKP/Kubernetes)
  • Coder CLI (system): v2.31.6 (Slim build)
  • Workspace template: Kubernetes-based

Steps to Reproduce

  1. Install Mux on Windows
  2. Configure Coder Runtime pointed at a self-hosted Coder deployment
  3. Create a workspace using the Coder Runtime
  4. Attempt to start an agent session

Expected Behavior

Mux connects to the Coder workspace via SSH and the agent session starts.

Actual Behavior

Connection fails immediately with:

Stream Error: runtime_start_failed
Failed to reach SSH host: SSH2 connection failed: SSH connection to <workspace>.mux--coder
is in backoff and maxWaitMs exceeded. Last error: Premature close

Logs show repeated ssh2-proxy-socket errors:

Stream error {"label":"ssh2-proxy-socket","code":"ERR_STREAM_PREMATURE_CLOSE","message":"Premature close"}
Error: Premature close
    at Socket.onclose (node:internal/streams/end-of-stream:171:30)

Diagnosis

The ProxyCommand in ~/.ssh/config (written by Mux) is correct and works via system OpenSSH:

# --- START MUX CODER SSH ---
Host *.mux--coder
    ProxyCommand "C:\Users\mathomas\coder.exe" "ssh" "--stdio" "--hostname-suffix" "mux--coder" "%h"
# --- END MUX CODER SSH ---

Verified the ProxyCommand works directly:

PS> & "C:\Users\mathomas\coder.exe" ssh --stdio --hostname-suffix mux--coder max-test.mux--coder
SSH-2.0-Go    # ← banner exchange succeeds

And coder ssh works perfectly:

PS> coder ssh max-test -- echo "hello"
hello

The issue is that Mux's Node.js ssh2 library receives the proxy stream but the socket closes before the SSH handshake completes. No key exchange, algorithm negotiation, or auth errors appear in logs — just immediate Premature close on every attempt.

Additional context: version mismatch in earlier logs

Earlier log entries also revealed that Mux's Coder Runtime uses an internal Coder CLI (v2.30.5 in the CoderSSHRuntime.ts code path) that is separate from the system Coder CLI. This caused version mismatch errors against the self-hosted server even after the system CLI was updated. It's unclear whether the Premature close issue is caused by or related to the internal CLI version.

Workaround

Switch from Coder Runtime to SSH Runtime using the host alias from coder config-ssh:

  • Runtime: SSH
  • SSH Host: coder.<workspace-name>

This bypasses Mux's internal ssh2 library and uses the system OpenSSH client, which handles the ProxyCommand correctly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions