vectordotdev/vector · error
Failed to set up SIGINT handler.
Error message
Failed to set up SIGINT handler.
What it means
tokio's signal(SignalKind::interrupt()) registers a Unix signal handler and returns io::Result; Vector registers SIGINT inside os_signals() and unwraps with expect. If registration fails (signal syscalls blocked by the sandbox, handler/resource limits hit, or too many registrations in one process), Vector panics during startup. The four sibling expects cover SIGINT, SIGTERM, SIGQUIT and SIGHUP.
Source
Thrown at src/signal.rs:196
}
/// Shutdown active signal handlers.
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");View on GitHub (pinned to 3708c39b12)
Solutions
- Run with the default container seccomp profile or allow signal-related syscalls (rt_sigaction, signalfd) in the custom profile
- Raise the file-descriptor limit (ulimit -n 65536, or LimitNOFILE= in systemd) if fd exhaustion is the cause
- If supervising Vector, prefer its API or a clean exec-based handoff instead of installing conflicting handlers in the same process
- Reproduce on the host outside the sandbox to confirm the environment, not the config, is at fault
Example fix
# before: custom seccomp blocks signal syscalls, Vector panics at boot docker run --security-opt seccomp=strict.json vector:latest # after: default profile (or unconfined for diagnosis) docker run vector:latest # and raise fd limits where needed: # ulimit -n 65536
Defensive patterns
Strategy: validation
Validate before calling
# fail fast before launching Vector [ "$(ulimit -n)" -ge 4096 ] || ulimit -n 4096 vector validate /etc/vector/vector.toml && exec vector --config /etc/vector/vector.toml
Prevention
- Run containers with the default seccomp profile; allowlist rt_sigaction and signalfd syscalls if customizing
- Keep RLIMIT_NOFILE high (LimitNOFILE=65536) on systemd/docker units
- Register signal handlers once per process when embedding Vector; share the stream across tasks
When it happens
Trigger: Starting Vector in an environment where signal(2)/signalfd registration fails for SIGINT: a container seccomp/apparmor profile blocking signal syscalls, exhaustion of the fd/handler budget by many embedded runtimes (test harnesses), or a platform without the signal kind.
Common situations: Overly restrictive Docker/Kubernetes seccomp profiles; custom supervisors chaining signal handling; test harnesses that repeatedly create Tokio runtimes registering handlers; very low RLIMIT_NOFILE.
Related errors
- Failed to set up SIGTERM handler.
- Failed to set up SIGQUIT handler.
- Failed to set up SIGHUP handler.
- concurrent map task cancelled outside of our control
- Unable to create async runtime
AI-assisted analysis of vectordotdev/vector@3708c39b12 (2026-08-20).
Data as JSON: /api/errors/1be83887958b2f43.
Report an issue: GitHub.