herdrdev/herdr · error

remote client exited with {status}

Error message

remote client exited with {status}

What it means

The spawned remote client process (e.g. an SSH-attached herdr client) exited with a non-success status code. The wrapper rethrows it as io::ErrorKind::Interrupted with the process's ExitStatus formatted into the message. It means the remote side of an attach session terminated abnormally.

Source

Thrown at src/remote/attach.rs:2138

    let status = Command::new(exe)
        .arg("client")
        .env(
            crate::server::socket_paths::CLIENT_SOCKET_PATH_ENV_VAR,
            local_socket,
        )
        .env("HERDR_RENDER_ENCODING", "terminal-ansi")
        .env(REATTACH_COMMAND_ENV_VAR, reattach_command)
        .env(REMOTE_KEYBINDINGS_ENV_VAR, keybindings.as_str())
        .env_remove(crate::api::SOCKET_PATH_ENV_VAR)
        .stdin(Stdio::inherit())
        .stdout(Stdio::inherit())
        .stderr(Stdio::inherit())
        .status()?;

    if status.success() {
        Ok(())
    } else {
        Err(io::Error::new(
            io::ErrorKind::Interrupted,
            format!("remote client exited with {status}"),
        ))
    }
}

fn local_forward_socket_path(target: &str, session_name: &str) -> PathBuf {
    let pid = std::process::id();
    let target_clean = sanitize_path_component(target);
    let session_clean = sanitize_path_component(session_name);
    let readable_name = format!("herdr-remote-{pid}-{target_clean}-{session_clean}.sock");
    let target_prefix: String = target_clean.chars().take(8).collect();
    let hash = short_socket_hash(target, session_name);
    let short_name = format!("herdr-r-{pid}-{target_prefix}-{hash}.sock");
    crate::platform::remote_bridge_endpoint_path(&readable_name, &short_name)
}

#[cfg(all(test, unix))]

View on GitHub (pinned to f457cff4f2)

Solutions

  1. Check the child's exit status in the message (exit code vs signal) to identify crash vs clean nonzero exit
  2. Run the remote client command manually over ssh to see its stderr
  3. Verify the remote herdr binary exists and is a compatible version
  4. Check network/SSH stability if the status indicates signal termination (e.g. SIGKILL/SIGTERM)
Defensive patterns

Strategy: try-catch

Try / catch

match attach_result { Ok(()) => {}, Err(e) if e.kind() == io::ErrorKind::Interrupted && e.to_string().contains("remote client exited") => { tracing::warn!("remote attach ended: {e}"); }, Err(e) => return Err(e) }

Prevention

When it happens

Trigger: Calling the remote attach helper that spawns a child herdr client with inherited stdio and checking status.success(); any nonzero exit code or signal termination of that child produces this error.

Common situations: SSH connection dropped mid-session, remote herdr binary missing or crashing, remote shell exiting due to auth failure, or the remote client hitting its own fatal error.

Related errors


AI-assisted analysis of herdrdev/herdr@f457cff4f2 (2026-08-28). Data as JSON: /api/errors/3ccc9d19a231201a. Report an issue: GitHub.