herdrdev/herdr · critical
ssh bridge exited with {status}
Error message
ssh bridge exited with {status} What it means
After the SSH bridge child exits, a non-successful exit status is wrapped in this ConnectionAborted error. It means the ssh transport process itself terminated abnormally (non-zero exit), breaking the bridged connection.
Source
Thrown at src/remote/attach.rs:1864
let mut stream_to_child = stream.try_clone()?;
let mut child_to_stream = stream;
let upload = thread::spawn(move || {
let _ = copy_flush(&mut stream_to_child, &mut child_stdin);
});
let download = thread::spawn(move || {
let _ = copy_flush(&mut child_stdout, &mut child_to_stream);
let _ = crate::ipc::shutdown_local_stream_write(&child_to_stream);
});
let status = child.wait()?;
let _ = upload.join();
let _ = download.join();
if status.success() {
Ok(())
} else {
Err(io::Error::new(
io::ErrorKind::ConnectionAborted,
format!("ssh bridge exited with {status}"),
))
}
}
#[cfg(windows)]
fn bridge_connection(
stream: crate::ipc::LocalStream,
target: &str,
remote_herdr: &RemoteHerdr,
session_name: &str,
ssh_options: Option<&ManagedSshOptions>,
bridge_stop: &Arc<AtomicBool>,
) -> io::Result<()> {
let mut command = Command::new("ssh");
apply_managed_ssh_options(&mut command, ssh_options);
commandView on GitHub (pinned to f457cff4f2)
Solutions
- Run ssh <target> manually to confirm authentication and connectivity work
- Check ssh config (~/.ssh/config) for the target, ProxyJump, and identity settings
- Look at inherited stderr output from ssh for the actual failure reason
- Verify network stability / VPN and retry
- Enable SSH keepalives (ServerAliveInterval) for flaky links
Example fix
# reproduce manually to see the real error ssh user@host herdr server status
Defensive patterns
Strategy: retry
Validate before calling
fn target_reachable(target: &str) -> bool {
std::process::Command::new("ssh")
.args([target, "true"])
.output()
.map(|o| o.status.success())
.unwrap_or(false)
} Try / catch
match bridge() {
Err(e) if e.kind() == std::io::ErrorKind::ConnectionAborted => {
if target_reachable(target) { bridge() } else { Err(e) }
}
r => r,
} Prevention
- Test manual ssh connectivity to the target before attaching
- Configure ServerAliveInterval/CountMax for flaky networks
- Capture ssh stderr (inherited) to diagnose exit reasons
When it happens
Trigger: ssh exits non-zero during the bridge session: authentication failure, network drop, remote command failure, or ssh being killed by a signal — observed after the upload/download copy threads join.
Common situations: SSH key not loaded/agent issues, network interruption, remote herdr socket command failing, ServerAliveInterval killing dead connections, or ssh config errors (bad ProxyJump).
Related errors
- failed to start ssh bridge: {err}
- ssh bridge stdin missing
- ssh bridge stdout missing
- remote bridge upload failed: {err}
- remote bridge download failed: {err}
AI-assisted analysis of herdrdev/herdr@f457cff4f2 (2026-08-28).
Data as JSON: /api/errors/8328468d02547e8b.
Report an issue: GitHub.