Skip to content

Windows: remote PC connect hangs because Windows OpenSSH never exits when spawned headless #1944

Closed

Description

@nahwan-kim

Summary

On a Windows PC, connecting a saved herdr machine (a macOS host) never finishes. The "Checking the remote environment…" step runs until the 90 s ssh.run timeout. The cause is Windows OpenSSH: when ssh.exe is spawned headless the way the server spawns it (Bun.spawn, stdin: "ignore", piped stdout/stderr, under the detached + windowsHide server), the remote command completes and its output arrives, but ssh.exe never exits.

Environment

  • Ovis 0.4.16 (herdr plugin), herdr 0.9.3 on Windows 11 (10.0.26200), PowerShell 7.6
  • Windows OpenSSH client OpenSSH_for_Windows_9.5p2 (System32). The portable 10.4.0.0p1-Preview build behaves the same.
  • Remote: macOS, herdr 0.9.5. Plain ssh host cmd from an interactive terminal works.

What I observed

Process trace of one Connect click (children of the Ovis server process):

  • ssh … -T host exit (the proof): exits after about 1 s
  • ssh … -N -T host: stays up, as expected
  • ssh … -T host "sh -c '…uname -s…'" (posixHost.inspect): never exits. The job then falls back to the PowerShell probe and fails.

Minimal reproduction (outside Ovis)

Run this from a headless context, e.g. a non-tty ssh windows-pc 'bun test.ts':

for (const cmd of ["exit", "echo hi", "echo hi >&2"]) {
  const proc = Bun.spawn(["ssh", "-o", "BatchMode=yes", "-T", "mac-host", cmd], { stdin: "ignore", stdout: "pipe", stderr: "pipe" });
  const timer = setTimeout(() => proc.kill(), 8000);
  const [out, , code] = await Promise.all([new Response(proc.stdout).text(), new Response(proc.stderr).text(), proc.exited]);
  clearTimeout(timer);
  console.log(cmd, code, JSON.stringify(out));
}
command Windows OpenSSH 9.5 / 10.4 headless same, with a console (ssh -tt session) Git for Windows ssh.exe 10.5 headless
exit exits, 0 exits, 0 exits, 0
echo hi output hi, then hangs (killed, 143) exits, 0 exits, 0
echo hi >&2 stderr hi, then hangs exits, 0 exits, 0

-n, -E logfile, -o LogLevel=QUIET, -tt, and a file as stdin do not help. Any byte written by the remote command is enough to trigger the hang. The upstream Win32-OpenSSH report closest to this is PowerShell/Win32-OpenSSH#2448.

Workaround in use

I copied Git for Windows' ssh.exe, ssh-keygen.exe, sftp.exe and their msys-*.dll (plus etc/nsswitch.conf) into a folder placed first on the system PATH. With that, the same probes return in about 0.2 s.

Suggestion

On Windows, allow overriding the client binary (e.g. OVIS_SSH, plus ssh-keygen/sftp), or prefer Git for Windows' ssh when it is installed. Alternatively, spawn ssh.exe with a console attached.

Activity

  1. added 2 commits that reference this issue on Oct 26, 2026
    b70a8c8
    ef6ff17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions