vectordotdev/vector · error
Failed to set up SIGQUIT handler.
Error message
Failed to set up SIGQUIT handler.
What it means
The Unix signal handler registers tokio's `signal` streams for SIGINT, SIGTERM, SIGQUIT, and SIGHUP inside a dedicated runtime. Each registration is asserted; failing to install the SIGQUIT handler panics with "Failed to set up SIGQUIT handler.". Registration fails when signal handling cannot be set up at the OS level.
Solutions
- Ensure the signal setup is invoked from within an active Tokio runtime (the wrapper already uses block_on — do not call it from a torn-down runtime).
- Check the container seccomp/apparmor profile permits `rt_sigaction`/signalfd syscalls.
- Verify the platform supports tokio's signal driver (Unix only path) and that signal handlers aren't exhausted.
Example fix
// before tokio::runtime::Runtime::new().unwrap().shutdown_timeout(Duration::from_secs(0)); signal_handler(); // panics: runtime gone // after let rt = tokio::runtime::Runtime::new().unwrap(); rt.block_on(signal_handler()); // register while runtime is live
Defensive patterns
Strategy: try-catch
Validate before calling
// Ensure we are inside a runtime before installing handlers: assert!(tokio::runtime::Handle::try_current().is_ok(), "signal setup requires an active tokio runtime");
Try / catch
match tokio::signal::unix::signal(tokio::signal::unix::SignalKind::quit()) {
Ok(rx) => { /* proceed */ }
Err(e) => { eprintln!("SIGQUIT handler unavailable: {e}; falling back to default termination"); }
} Prevention
- Only call signal setup from within a live Tokio runtime.
- Check container seccomp profiles allow signalfd/rt_sigaction syscalls.
- Test signal handling in the target runtime environment (Docker, systemd) before production rollout.
When it happens
Trigger: Calling the signal setup function outside a Tokio runtime context or where the runtime has been shut down, or when the OS refuses to install the handler (signal mask/rlimit issues, unsupported platform).
Common situations: Running vector in minimal containers where signal syscalls are blocked by seccomp profiles; calling the signal machinery from a non-async context; ephemeral runtimes torn down before registration.
Related errors
- Failed to set up SIGHUP handler.
- Failed to set up SIGINT handler.
- Failed to set up SIGTERM handler.
- double thread initialization
- should not fail to build current-thread runtime
AI-assisted analysis of vectordotdev/vector@bdb87aeaa4 (2026-09-16).
Data as JSON: /api/errors/ea0e3d6b352c556c.
Report an issue: GitHub.
Appendix: source
Thrown at src/signal.rs:199
pub fn clear(&mut self) {
for shutdown_tx in self.shutdown_txs.drain(..) {
// An error just means the channel was already shut down; safe to ignore.
_ = shutdown_tx.send(());
}
}
}
/// Signals from OS/user.
#[cfg(unix)]
fn os_signals(runtime: &Runtime) -> impl Stream<Item = SignalTo> + use<> {
use tokio::signal::unix::{SignalKind, signal};
// The `signal` function must be run within the context of a Tokio runtime.
runtime.block_on(async {
let mut sigint = signal(SignalKind::interrupt()).expect("Failed to set up SIGINT handler.");
let mut sigterm =
signal(SignalKind::terminate()).expect("Failed to set up SIGTERM handler.");
let mut sigquit = signal(SignalKind::quit()).expect("Failed to set up SIGQUIT handler.");
let mut sighup = signal(SignalKind::hangup()).expect("Failed to set up SIGHUP handler.");
async_stream::stream! {
loop {
let signal = tokio::select! {
_ = sigint.recv() => {
info!(message = "Signal received.", signal = "SIGINT");
SignalTo::Shutdown(None)
},
_ = sigterm.recv() => {
info!(message = "Signal received.", signal = "SIGTERM");
SignalTo::Shutdown(None)
} ,
_ = sigquit.recv() => {
info!(message = "Signal received.", signal = "SIGQUIT");
SignalTo::Quit
},
_ = sighup.recv() => {View on GitHub (pinned to bdb87aeaa4)