BloopAI/vibe-kanban · error
relay session error: {error}
Error message
relay session error: {error} What it means
The relay server's run_control_channel iterates inbound streams from the client's yamux session. Since clients do not open server-initiated streams in the current design, any Err from session.next() is fatal for that control channel and is returned as 'relay session error: {error}'. The handler then tears down the control connection.
Source
Thrown at crates/relay-tunnel-core/src/server.rs:41
/// shared control handle that can be used to proxy requests over new streams.
pub async fn run_control_channel<F, Fut>(socket: WebSocket, on_connected: F) -> anyhow::Result<()>
where
F: FnOnce(SharedControl) -> Fut,
Fut: Future<Output = ()>,
{
let ws_io = axum_ws_stream_io(socket);
let mut session = Session::new_server(ws_io, yamux_config());
let control = Arc::new(Mutex::new(session.control()));
on_connected(control).await;
while let Some(stream_result) = session.next().await {
match stream_result {
Ok(_stream) => {
// The client side does not currently open server-initiated streams.
}
Err(error) => {
return Err(anyhow::anyhow!("relay session error: {error}"));
}
}
}
Ok(())
}
/// Proxies one HTTP request over a new yamux stream using the shared control.
pub async fn proxy_request_over_control(
control: &Mutex<Control>,
request: Request,
strip_prefix: &str,
) -> Response {
let stream = {
let mut control = control.lock().await;
match control.open_stream().await {
Ok(stream) => stream,
Err(error) => {View on GitHub (pinned to 4deb7eca8f)
Solutions
- Treat as a client-side connection issue: have the client reconnect; the server will accept a new control channel.
- Inspect '{error}' and server logs to distinguish transient transport drops from protocol violations.
- Raise proxy/load-balancer idle timeouts so long-lived control channels aren't severed.
- Ensure client and server use compatible yamux versions and keepalive settings.
Defensive patterns
Strategy: try-catch
Try / catch
// at the handle_control_channel boundary
if let Err(e) = run_control_channel(session, ...).await {
tracing::warn!(error=?e, "control channel ended; awaiting client reconnect");
// do not crash the server; the client will re-establish
} Prevention
- Keep control-channel errors contained per-connection; never crash the relay server.
- Set proxy/LB idle timeouts above the control channel keepalive interval.
- Keep client and server yamux configurations compatible.
- Correlate server-side errors with client reconnect logs.
When it happens
Trigger: A yamux protocol error occurs on the server side of the control channel: transport read/write failure, frame corruption, stream reset, or the client's connection dying unexpectedly while the server drains the session.
Common situations: Client crashes or network drops mid-session; relay server behind a proxy/load balancer with short idle timeouts; TLS/WebSocket layer errors surfacing as yamux errors; client-server yamux configuration mismatch.
Related errors
- Relay control channel closed
- Relay yamux session error: {e}
- Host returned HTTP ${response.status}
- Auth methods lookup failed (${res.status})
- Session refresh failed. Please sign in again.
AI-assisted analysis of BloopAI/vibe-kanban@4deb7eca8f (2026-08-29).
Data as JSON: /api/errors/af0331c1eca4b335.
Report an issue: GitHub.