{"record":{"id":"ffa9d39197a04215","repo":"quickwit-oss/quickwit","slug":"registering-a-signal-handler-for-sigterm-should-no","errorCode":null,"errorMessage":"registering a signal handler for SIGTERM should not fail","messagePattern":"registering a signal handler for SIGTERM should not fail","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"quickwit/quickwit-cli/src/service.rs","lineNumber":78,"sourceCode":"    ctrl_c().await;\n    println!(\n        \"{} Graceful shutdown initiated. Waiting for ingested data to be indexed. This may take a \\\n         few minutes. Press Ctrl+C again to force shutdown.\",\n        \"❢\".color(BLUE_COLOR)\n    );\n    tokio::spawn(async {\n        ctrl_c().await;\n        println!(\n            \"{} Quickwit was forcefully shut down. Some data might not have been indexed.\",\n            \"✘\".color(RED_COLOR)\n        );\n        std::process::exit(1);\n    });\n}\n\nasync fn listen_sigterm() {\n    signal::unix::signal(signal::unix::SignalKind::terminate())\n        .expect(\"registering a signal handler for SIGTERM should not fail\")\n        .recv()\n        .await;\n    info!(\"SIGTERM received\");\n}\n\nasync fn listen_sighup() {\n    let mut sighup = signal::unix::signal(signal::unix::SignalKind::hangup())\n        .expect(\"registering a signal handler for SIGHUP should not fail\");\n\n    while sighup.recv().await.is_some() {\n        info!(\"SIGHUP received\");\n        reload_tls_cert();\n    }\n}\n\nimpl RunCliCommand {\n    pub fn parse_cli_args(mut matches: ArgMatches) -> anyhow::Result<Self> {\n        let config_uri = matches","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/quickwit-oss/quickwit/blob/a39730c5cdcd1a4fe798403737ae293999ea21f8/quickwit/quickwit-cli/src/service.rs#L60-L96","documentation":"In listen_sigterm, the code registers a tokio unix signal handler for SIGTERM. Registration fails only if the signal number is out of range or signals cannot be registered; the expect asserts this cannot happen because a server that cannot catch SIGTERM cannot drain in-flight indexing before being killed.","triggerScenarios":"signal::unix::signal(SignalKind::terminate()) returning Err while executing the quickwit serve command on Unix — only when signal handler registration is blocked by the OS.","commonSituations":"Hardened containers with seccomp filters stripping rt_sigaction; unusual init setups with signal masks that leak SIGTERM to blocked; running on platforms where unix signal APIs are unavailable (would not compile).","solutions":["Deploy quickwit under a normal init/container runtime that permits signal registration.","Allow the rt_sigaction syscall in seccomp/AppArmor profiles.","Replace the expect with graceful error handling that logs and falls back to default termination behavior."],"exampleFix":"// before\nsignal::unix::signal(signal::unix::SignalKind::terminate())\n    .expect(\"registering a signal handler for SIGTERM should not fail\")\n// after\nlet mut sigterm = signal::unix::signal(signal::unix::SignalKind::terminate())\n    .context(\"failed to register SIGTERM handler\")?;","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"let mut sigterm = signal::unix::signal(signal::unix::SignalKind::terminate())\n    .map_err(|err| anyhow::anyhow!(\"SIGTERM handler registration failed: {err}\"))?;","preventionTips":["Deploy under init systems that do not block SIGTERM.","Allow signal syscalls in container security profiles.","Test graceful shutdown (`kubectl delete pod`) in CI to catch registration regressions early."],"tags":["cli","signals","unix","panic"],"backgroundTag":"unsupported-platform","analyzedSha":"a39730c5cdcd1a4fe798403737ae293999ea21f8","analyzedAt":"2026-09-08T13:19:37.784Z","contentChangedAt":"2026-09-08T13:19:37.784Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}