herdrdev/herdr · error · ClientError::ConnectionLost
server closed connection
Error message
server closed connection
What it means
The client's From<protocol::FramingError> impl maps FramingError::UnexpectedEof to ClientError::ConnectionLost with UnexpectedEof and the message 'server closed connection' (src/client/mod.rs:337). UnexpectedEof means the framed stream ended mid-read — the TCP/local socket was closed by the peer before a complete message frame arrived.
Source
Thrown at src/client/mod.rs:337
}
}
}
impl std::error::Error for ClientError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
ClientError::ConnectionFailed(err) => Some(err),
ClientError::ConnectionLost(err) => Some(err),
ClientError::Protocol(err) => Some(err),
_ => None,
}
}
}
impl From<protocol::FramingError> for ClientError {
fn from(err: protocol::FramingError) -> Self {
match err {
protocol::FramingError::UnexpectedEof => ClientError::ConnectionLost(io::Error::new(
io::ErrorKind::UnexpectedEof,
"server closed connection",
)),
protocol::FramingError::Io(err) => ClientError::ConnectionLost(err),
err => ClientError::Protocol(err),
}
}
}
// ---------------------------------------------------------------------------
// Terminal setup / restore
// ---------------------------------------------------------------------------
/// Sets up the terminal for client mode (raw mode, optional mouse, keyboard enhancements).
///
/// Returns a guard that restores the terminal when dropped.
fn setup_terminal(mouse_capture: bool) -> io::Result<TerminalGuard> {
setup_terminal_with_capabilities(true, mouse_capture)View on GitHub (pinned to f457cff4f2)
Solutions
- Check that the herdr server is running: herdr status or herdr server list; restart with herdr daemon start / herdr server start
- Inspect server logs for a crash or panic at the moment of disconnect
- Clear stale sockets if the server died without cleanup, then reconnect
- If it recurs, report the server-side panic backtrace from the logs
Defensive patterns
Strategy: retry
Validate before calling
// verify the server is reachable before connecting herdr status || herdr daemon start
Type guard
fn is_connection_lost(e: &ClientError) -> bool {
matches!(e, ClientError::ConnectionLost(err) if err.kind() == io::ErrorKind::UnexpectedEof)
} Try / catch
match client.run() {
Err(e) if is_connection_lost(&e) => reconnect_with_backoff(),
r => r,
} Prevention
- Monitor the server process and restart it automatically
- Handle ConnectionLost by reconnecting rather than surfacing a fatal error
When it happens
Trigger: Any client read path decoding a protocol frame hits EOF because the herdr server process exited, crashed, or closed the socket while the client was reading (handshake, event loop, or attach stream).
Common situations: Server killed or OOM-killed mid-session, herdr update restarting the server, server panic, or a socket path pointing at a dead server's stale socket being cleaned up.
Related errors
- stream frame header is too large
- stream ended mid-frame
- expected Welcome message
- curl failed: {err}
- api request line is too large
AI-assisted analysis of herdrdev/herdr@f457cff4f2 (2026-08-28).
Data as JSON: /api/errors/8743a307bc8f41ea.
Report an issue: GitHub.