{"record":{"id":"b2d80db4cd07a196","repo":"quickwit-oss/quickwit","slug":"registering-a-signal-handler-for-sighup-should-not","errorCode":null,"errorMessage":"registering a signal handler for SIGHUP should not fail","messagePattern":"registering a signal handler for SIGHUP should not fail","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"quickwit/quickwit-cli/src/service.rs","lineNumber":86,"sourceCode":"        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\n            .remove_one::<String>(\"config\")\n            .map(|uri_str| Uri::from_str(&uri_str))\n            .expect(\"`config` should be a required arg.\")?;\n        let services = matches\n            .remove_many::<String>(\"service\")\n            .map(|values| {\n                let services: Result<HashSet<_>, _> = values\n                    .into_iter()","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/quickwit-oss/quickwit/blob/a39730c5cdcd1a4fe798403737ae293999ea21f8/quickwit/quickwit-cli/src/service.rs#L68-L104","documentation":"listen_sighup registers a SIGHUP handler used to hot-reload TLS certificates. signal::unix::signal(SignalKind::hangup()) registration is expected to always succeed; the expect panics otherwise, since losing SIGHUP support would mean TLS certs can no longer be reloaded without a restart.","triggerScenarios":"Executing the quickwit serve command on Unix when registering the SIGHUP handler fails — signal number registration rejected by the OS or runtime constraints.","commonSituations":"Same sandbox causes as SIGTERM: seccomp-restricted containers, blocked signals inherited from a supervisor, minimal libc environments.","solutions":["Run in an environment that permits SIGHUP registration (standard Docker/K8s/systemd do).","Fix container syscall allow-lists to include rt_sigaction.","Handle the Err explicitly: log a warning that TLS hot-reload is disabled and skip the reload loop."],"exampleFix":"// before\nlet mut sighup = signal::unix::signal(signal::unix::SignalKind::hangup())\n    .expect(\"registering a signal handler for SIGHUP should not fail\");\n// after\nlet Ok(mut sighup) = signal::unix::signal(signal::unix::SignalKind::hangup()) else {\n    error!(\"failed to register SIGHUP handler; TLS hot-reload disabled\");\n    return;\n};","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"let Ok(mut sighup) = signal::unix::signal(signal::unix::SignalKind::hangup()) else {\n    error!(\"SIGHUP handler unavailable; TLS hot-reload disabled\");\n    return;\n};","preventionTips":["Verify SIGHUP delivery (`kill -HUP <pid>`) after container profile changes.","Keep a fallback path: full restart renews TLS certs even if hot-reload is unavailable.","Log registration failures instead of panicking so the server still serves traffic."],"tags":["cli","signals","tls","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"}