tracel-ai/burn · error

failed to install signal handler

Error message

failed to install signal handler

What it means

On Unix targets, os_shutdown_signal registers a SIGTERM listener via tokio::signal::unix::signal and expects installation to succeed. Failure means the OS/registry rejected creating the signal stream.

Source

Thrown at crates/burn-remote/src/server/spawn.rs:36

/// Resolve when the process is asked to stop (Ctrl+C, or `SIGTERM` on Unix).
///
/// The single shutdown trigger shared by the turnkey WebSocket and Iroh server entry points.
#[cfg(all(
    not(target_family = "wasm"),
    any(feature = "websocket", feature = "iroh")
))]
pub(crate) async fn os_shutdown_signal() {
    let ctrl_c = async {
        tokio::signal::ctrl_c()
            .await
            .expect("failed to install Ctrl+C handler");
    };

    #[cfg(unix)]
    let terminate = async {
        tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate())
            .expect("failed to install signal handler")
            .recv()
            .await;
    };
    #[cfg(not(unix))]
    let terminate = std::future::pending::<()>();

    tokio::select! {
        _ = ctrl_c => {},
        _ = terminate => {},
    }
}

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Ensure the parent process doesn't block SIGTERM before spawning the server
  2. Verify the runtime environment allows unix signal registration (no restrictive seccomp/sandbox rule)
  3. Replace the default shutdown signal with a custom future if SIGTERM handling is unavailable
  4. Check available file descriptors / raise ulimit -n, since signal streams consume fds

Example fix

// before
tokio::signal::unix::signal(SignalKind::terminate()).expect("failed to install signal handler");
// after
match tokio::signal::unix::signal(SignalKind::terminate()) {
    Ok(mut sig) => sig.recv().await,
    Err(e) => { log::warn!("SIGTERM handler unavailable: {e}; falling back"); std::future::pending::<()>().await }
}
Defensive patterns

Strategy: fallback

Validate before calling

// Ensure SIGTERM is not blocked by this process before starting the server
unsafe { assert!(!signal_blocked(libc::SIGTERM)); }

Try / catch

std::panic::catch_unwind(|| server_thread.join())
    .map_err(|_| anyhow!("server aborted: could not install SIGTERM handler"))?;

Prevention

When it happens

Trigger: Server startup with websocket/iroh features on Unix where SignalKind::terminate registration fails — signal mask manipulated by parent process, fd/resource exhaustion, or unsupported platform quirks.

Common situations: Containers/init systems that block or mask SIGTERM; exceeding per-process signal-stream limits; running under sandboxes that forbid signal registration.

Related errors


AI-assisted analysis of tracel-ai/burn@d16f7ba2ed (2026-09-05). Data as JSON: /api/errors/a4779accc9d66f3f. Report an issue: GitHub.