atuinsh/atuin · error
failed to register sigterm handler
Error message
failed to register sigterm handler
What it means
`shutdown_signal()` in the Atuin daemon registers a SIGTERM handler via `tokio::signal::unix::signal`. Panicking here means the OS refused to install the signal handler — the signal event source could not be created. Without it the daemon cannot shut down gracefully on SIGTERM.
Solutions
- Ensure the daemon runs inside a properly configured tokio multi-thread runtime with the `signal` feature
- Check `ulimit -i` (RLIMIT_SIGPENDING) and raise it if exhausted
- Investigate leaked signal handler registrations in long-running wrapper processes
- Update tokio — older versions had signal-driver edge cases
Example fix
// before
#[tokio::main]
async fn main() { /* runtime without io/signal driver */ }
// after
#[tokio::main(flavor = "multi_thread")]
async fn main() { /* ensure tokio features "rt-multi-thread", "signal", "macros" */ } Defensive patterns
Strategy: try-catch
Try / catch
// Use the Result-returning API instead of expect:
let mut term = tokio::signal::unix::signal(SignalKind::terminate())
.map_err(|e| BootError::SignalHandler(e))?; Prevention
- Enable tokio features: rt-multi-thread, macros, signal
- Check RLIMIT_SIGPENDING (`ulimit -i`) on hosts running many processes
- Avoid nesting signal registrations in loops without dropping old handlers
When it happens
Trigger: `SignalKind::terminate()` handler registration failing inside `shutdown_signal()` during `boot()` — typically when tokio's signal driver is unavailable or the process hit a resource/signal limit.
Common situations: Calling daemon boot outside a tokio runtime with the signal driver enabled (e.g. `current_thread` runtime built without `rt` features or via block_on misuse); RLIMIT_SIGPENDING exhaustion from leaked signal handlers; unusual runtimes without full signal support.
Related errors
- failed to register sigint handler
- failed to listen for ctrl+c
- output-capture delete task panicked
- output-capture read task panicked
- output-capture reclaim task panicked
AI-assisted analysis of atuinsh/atuin@c0c717ab04 (2026-09-12).
Data as JSON: /api/errors/c5b66df5648797d3.
Report an issue: GitHub.
Appendix: source
Thrown at crates/atuin-daemon/src/lib.rs:135
handle,
)
.await?;
// Run the daemon event loop
daemon.run_event_loop().await?;
// Stop all components on shutdown
daemon.stop_components().await;
tracing::info!("daemon shut down complete");
Ok(())
}
/// Wait for a shutdown signal (Ctrl+C or SIGTERM).
#[cfg(unix)]
async fn shutdown_signal() {
let mut term = tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate())
.expect("failed to register sigterm handler");
let mut int = tokio::signal::unix::signal(tokio::signal::unix::SignalKind::interrupt())
.expect("failed to register sigint handler");
tokio::select! {
_ = term.recv() => {},
_ = int.recv() => {},
}
}
/// Wait for a shutdown signal (Ctrl+C).
#[cfg(not(unix))]
async fn shutdown_signal() {
tokio::signal::ctrl_c().await.expect("failed to listen for ctrl+c");
}
View on GitHub (pinned to c0c717ab04)