Windows host: machine add always fails 'not ready for saved machines' because detached_server_daemon requires not-in-job, and every process is in a job on Windows 11 26200
Is this a reproducible bug?
- I confirm this is a reproducible bug, not a feature request, idea, question, contribution proposal, or direction check.
- I reproduced this bug on the version and environment reported below using the exact steps provided.
Current behavior
Against a Windows host, herdr machine add <host> --label X always ends with error: remote server is not ready for saved machines; machine was not saved, even after accepting the offered server restart, and every repeat produces the same result.
The saved-machine readiness gate needs the host server to report detached_server_daemon: true. On Windows that flag is derived from IsProcessInJob(hProcess, NULL) == FALSE (plus no console window). On Windows 11 build 26200 every process I can find is inside a job object, including explorer.exe, WindowsTerminal.exe, WmiPrvSE.exe, and every herdr server however it was launched, so the flag can never become true and the gate can never pass.
Related: #4205 and #3521 describe the same prompt appearing while restart_needed is false, on macOS. This report is the Windows side, where the flag is structurally unreachable and the consequence is that saved machines cannot be created at all.
What the client prints:
remote herdr server on <host> (session default) is currently running:
server: v0.9.1
prepared binary: 0.9.1
the remote server was started by a herdr build that may not survive SSH connection loss. restart it so network drops disconnect only this client.
This stops active remote pane processes, including shells, agents, dev servers, and tests.
restart the remote server now? [y/N] y
stopped the remote herdr server on <host>; it will restart when the remote client bridge attaches.
error: remote server is not ready for saved machines; machine was not savedherdr status server --json on the host, for the server the bridge relaunched (WMI Win32_Process.Create with DETACHED_PROCESS, no conhost.exe child, session 0), and identically for a server started from the Windows Terminal TUI:
{"status":"running","running":true,"version":"0.9.1","protocol":22,"capabilities":{"live_handoff":false,"detached_server_daemon":false,"endpoint_protocol_generation":1,"surface_interest":true,"health_check":true},"compatible":true,"endpoint_compatible":true,"socket":"C:\\Users\\<user>\\AppData\\Roaming\\herdr\\herdr.sock","session":null,"restart_needed":false,"server_binary_stale":false}IsProcessInJob(hProcess, NULL) through a small P/Invoke, on two different Windows 11 26200 machines:
WmiPrvSE.exe sid=0 inJob=True
explorer.exe sid=1 inJob=True
WindowsTerminal.exe sid=1 inJob=True
herdr.exe server (WMI relaunch) sid=0 inJob=True conhost children=0
herdr.exe server (TUI launched) sid=1 inJob=TrueWhere this appears to come from in the v0.9.1 source:
src/platform/windows.rs,current_process_is_detached_server_daemon(): true only ifGetConsoleWindow()is null andcurrent_process_is_in_job()isOk(false).src/remote/restart_policy.rs,remote_server_restart_reason():!detached_server_daemonyieldsDaemonDetach.src/remote/attach.rs,prepare_saved_ssh(): after the restart, any remaining restart reason maps to "remote server is not ready for saved machines".
The WMI relaunch correctly escapes the SSH session's kill-on-close job and uses DETACHED_PROCESS, but it still lands inside a job, so the freshly launched server reports false and the gate rejects it again.
Side effect worth knowing: for an Administrators-group account, Windows OpenSSH sessions carry the full high-integrity token (whoami /groups shows High Mandatory Level). The WMI relaunch from that session therefore produces a session-0, high-integrity server, and a normal herdr at the host's own keyboard then fails with access is denied (os error 5) until herdr server stop is run over SSH and the server is started again at the keyboard.
Expected behavior
Either machine add succeeds against a Windows host whose server was launched by herdr's own detached path, or the restart is not offered when it cannot change the outcome. Deriving the detached flag from current_job_kills_processes_on_close() (already used for the launch decision) rather than bare IsProcessInJob would match the intent on Windows.
Reproduction
- Host (Windows 11 26200, OpenSSH Server, key auth,
DefaultShellcmd.exe): startherdrfrom Windows Terminal so the default session is running. - Client (Windows 11 26200), in Command Prompt:
herdr machine add <host> --label "Desktop". - Answer
yat the restart prompt. Observestopped the remote herdr server ...followed byerror: remote server is not ready for saved machines; machine was not saved. herdr machine liston the client printsNo saved SSH machines.- Repeat step 2: identical outcome. On the host,
herdr status server --jsonshows"detached_server_daemon":falsefor the relaunched server.
herdr --remote <host> with N at the same prompt attaches and works normally in both directions between the two machines.
Impact
Saved machines cannot be used with a Windows host at all. Each accepted restart kills every pane process on the host, and the first time it also left the host's session unusable from its own keyboard (session-0, high-integrity server) until a manual stop.
Environment
- Herdr version: 0.9.1 stable on both machines, installed through
install.ps1 - Update channel (stable or preview): stable
- Operating system: Windows 11 Pro 10.0.26200 on both client and host
- Terminal: Windows Terminal 1.24 and plain Command Prompt on the client (same result)
- Shell, if relevant: PowerShell 7.6.6 MSI as the pane shell; host
DefaultShellcmd.exe (also reproduced with powershell.exe) - Relevant config, if any: default
[remote]settings; default session, no namedHERDR_SESSION; SSH key auth; Tailscale MagicDNS names
Source: herdrdev/herdr