vectordotdev/vector · error

Failed to set up SIGHUP handler.

Error message

Failed to set up SIGHUP handler.

What it means

Vector installs async signal handlers (SIGINT, SIGTERM, SIGQUIT, SIGHUP) via tokio::signal inside a Tokio runtime. The `signal()` call returns a Result; if registering the SIGHUP handler fails at the OS level, the code panics with this expect message. This typically means the OS refused the signal-handler registration (signal.h sigaction failure).

Solutions

  1. Ensure the signal setup runs inside a tokio runtime (runtime.block_on as in src/signal.rs)
  2. Check ulimit -n and raise the file-descriptor limit
  3. Verify the platform supports tokio signal handling (unix targets)
  4. Run with elevated/unrestricted container settings if seccomp blocks signal syscalls

Example fix

// before
let mut sighup = signal(SignalKind::hangup()).expect("Failed to set up SIGHUP handler.");
// after
let mut sighup = signal(SignalKind::hangup()).map_err(|e| anyhow!("Failed to set up SIGHUP handler: {e}"))?;
Defensive patterns

Strategy: fallback

Validate before calling

// rust: ensure a tokio runtime exists before registering signals
assert!(tokio::runtime::Handle::try_current().is_ok(), "signal setup requires a tokio runtime");
// shell: check fd headroom
ulimit -n

Type guard

fn runtime_available() -> bool { tokio::runtime::Handle::try_current().is_ok() }

Try / catch

let mut sighup = signal(SignalKind::hangup()).map_err(|e| anyhow!("SIGHUP handler setup failed: {e}"))?;

Prevention

When it happens

Trigger: Calling the signal-registration function outside a Tokio runtime context, OS resource exhaustion (too many signal handlers/fds), or a platform where SIGHUP registration via tokio's SignalKind::hangup is unsupported.

Common situations: Embedding Vector's signal setup in a non-tokio async executor or running in restricted containers/seccomp sandboxes that block sigaction; hitting process file-descriptor limits.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of vectordotdev/vector@bdb87aeaa4 (2026-09-16). Data as JSON: /api/errors/4f84a20afd541dd3. Report an issue: GitHub.

Appendix: source

Thrown at src/signal.rs:200

        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() => {
                        info!(message = "Signal received.", signal = "SIGHUP");

View on GitHub (pinned to bdb87aeaa4)