tracel-ai/burn · error
failed to install Ctrl+C handler
Error message
failed to install Ctrl+C handler
What it means
This panic comes from tokio's ctrl_c() inside os_shutdown_signal(), which installs a SIGINT handler for graceful shutdown. Installation can only fail if the tokio runtime has no signal driver (e.g. called via block_on with runtime disabled or io/signal driver not enabled). The library panics because shutdown signaling is considered essential and unrecoverable.
Source
Thrown at crates/burn-communication/src/util.rs:6
/// Utilities to help handle communication termination.
pub 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
- Enable tokio features 'signal' (and 'io-util'/'rt-multi-thread' as needed) in Cargo.toml and build the runtime with the default builder so the signal driver is registered.
- Ensure os_shutdown_signal is awaited inside a tokio runtime context, not on a bare std thread.
- If signal handling must be optional, replace the expect with graceful error propagation in a forked copy of util.rs.
Example fix
// before (custom runtime without signal driver)
let rt = tokio::runtime::Builder::new_current_thread().enable_io().build()?;
// after
let rt = tokio::runtime::Builder::new_multi_thread().enable_all().build()?;
// and in Cargo.toml: tokio = { version = "1", features = ["full"] } Defensive patterns
Strategy: validation
Validate before calling
// Ensure a full-featured tokio runtime wraps the call assert!(tokio::runtime::Handle::try_current().is_ok(), "must run inside a tokio runtime");
Prevention
- Enable tokio's 'signal' feature and .enable_all() on the runtime
- Only call start_iroh_async/start_websocket_async from within a tokio runtime
- Pin the tokio version and features in Cargo.toml (features = ["full"] for apps)
When it happens
Trigger: Calling start_iroh_async or start_websocket_async inside a runtime built without the signal feature, or on a runtime lacking signal handling support; tokio::signal::ctrl_c() returns Err before awaiting the signal.
Common situations: Embedding burn's communication server in a custom tokio runtime with feature flags stripped (no 'signal' support), using a current-thread runtime assembled manually, or running under an environment that forbids signal handler installation.
Related errors
- failed to install signal handler
- capture tensor operations must run inside CaptureDevice::cap
- Capture tensors do not support autodiff
- Autodiff should not wrap an autodiff tensor.
- Requires autodiff tensor.
AI-assisted analysis of tracel-ai/burn@d16f7ba2ed (2026-09-05).
Data as JSON: /api/errors/15d4fd0094169623.
Report an issue: GitHub.