block/buzz · error · anyhow::Error
Server error
Error message
Server error: {e} What it means
Identical failure point to 'TCP server error' but on the TCP-only code path of serve() (no UDS configured, non-unix or uds_path None): the axum::serve future for the main relay listener returned Err at crates/buzz-relay/src/main.rs:1390-1397. The bind already succeeded, so this is a runtime accept/serve-loop failure, not a startup config problem.
Solutions
- Raise fd limits (LimitNOFILE / ulimit -n) and check for fd growth: `ls /proc/<pid>/fd | wc -l` sampled over load.
- Extract the root cause from the anyhow chain — log with RUST_BACKTRACE=1 and RUST_LOG=buzz_relay=debug.
- Let the supervisor restart the relay; the graceful-shutdown wiring means a clean SIGTERM exit is normal, only a mid-run Err here is a defect.
- If correlated with media/git traffic, audit those handlers for leaked sockets/streams.
Defensive patterns
Strategy: try-catch
Validate before calling
# confirm healthy fd headroom before heavy traffic [ "$(ulimit -n)" -ge 65536 ] || echo "warning: low fd limit" >&2
Try / catch
// map the terminal serve error to a clean exit code for the supervisor
let exit = async {
if let Err(e) = serve(...).await {
eprintln!("Server error: {e}");
1
} else { 0 }
}; Prevention
- Default (no UDS) deployments still need fd headroom — set LimitNOFILE explicitly everywhere.
- Watch relay connection counts and idle-socket age to catch leaks before accept fails.
- Do not run the relay under a harness that drops the tokio runtime mid-serve; use the SIGTERM path.
- Alert on process restarts tagged with this message; a single occurrence is environmental, repeats indicate leakage.
When it happens
Trigger: The graceful-shutdown-wrapped axum::serve on the main router errors with: persistent accept() failures (EMFILE/ENFILE when the process fd limit is exhausted by connection churn), ENOMEM, or errors escaping hyper's per-connection handling. It also fires if the tokio runtime is dropped while serve() is still running, making the future fail instead of being polled to completion.
Common situations: Default deployment (no BUZZ_UDS_PATH) under connection storms hitting `ulimit -n`; fd leaks from git smart-HTTP or Blossom media uploads starving accept; running the relay inside a harness that drops the runtime at test end and surfaces the cancelled serve as an error.
Related errors
- TCP server error
- Failed to bind
- Failed to bind health port
- mesh endpoint bind on
- observer control subscribe error
AI-assisted analysis of block/buzz@ef2aa1ae38 (2026-08-20).
Data as JSON: /api/errors/dc9627bf276af257.
Report an issue: GitHub.
Appendix: source
Thrown at crates/buzz-relay/src/main.rs:1514
return Ok(());
}
#[cfg(not(unix))]
if config.uds_path.is_some() {
tracing::warn!("BUZZ_UDS_PATH set but UDS not supported on this platform");
}
// TCP-only path.
let mut tcp_rx = shutdown_tx.subscribe();
axum::serve(
tcp_listener,
router.into_make_service_with_connect_info::<std::net::SocketAddr>(),
)
.with_graceful_shutdown(async move {
tcp_rx.changed().await.ok();
})
.await
.map_err(|e| anyhow::anyhow!("Server error: {e}"))?;
let hard_shutdown = shutdown_handle
.await
.map_err(|e| anyhow::anyhow!("Shutdown task failed: {e}"))?;
hard_shutdown.abort();
Ok(())
}
/// Wait for SIGTERM (Unix) or Ctrl+C.
async fn shutdown_signal() {
#[cfg(unix)]
{
use tokio::signal::unix::{signal, SignalKind};
let mut sigterm = signal(SignalKind::terminate()).expect("install SIGTERM handler");
tokio::select! {
_ = tokio::signal::ctrl_c() => {},
_ = sigterm.recv() => {},
}View on GitHub (pinned to ef2aa1ae38)