{"record":{"id":"902d129577b4b203","repo":"tokio-rs/tokio","slug":"refusing-to-register-signal-signal","errorCode":null,"errorMessage":"Refusing to register signal {signal}","messagePattern":"Refusing to register signal (.+?)","errorType":"exception","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"tokio/src/signal/unix.rs","lineNumber":272,"sourceCode":"/// Those two operations should both be async-signal safe.\nfn action(globals: &'static Globals, signal: libc::c_int) {\n    globals.record_event(signal as EventId);\n\n    // Send a wakeup, ignore any errors (anything reasonably possible is\n    // full pipe and then it will wake up anyway).\n    let mut sender = &globals.sender;\n    drop(sender.write(&[1]));\n}\n\n/// Enables this module to receive signal notifications for the `signal`\n/// provided.\n///\n/// This will register the signal handler if it hasn't already been registered,\n/// returning any error along the way if that fails.\nfn signal_enable(signal: SignalKind, handle: &Handle) -> io::Result<()> {\n    let signal = signal.0;\n    if signal <= 0 || signal_hook_registry::FORBIDDEN.contains(&signal) {\n        return Err(Error::new(\n            ErrorKind::Other,\n            format!(\"Refusing to register signal {signal}\"),\n        ));\n    }\n\n    // Check that we have a signal driver running\n    handle.check_inner()?;\n\n    let globals = globals();\n    let siginfo = match globals.storage().get(signal as EventId) {\n        Some(slot) => slot,\n        None => return Err(io::Error::new(io::ErrorKind::Other, \"signal too large\")),\n    };\n\n    siginfo\n        .init\n        .get_or_init(|| {\n            unsafe { signal_hook_registry::register(signal, move || action(globals, signal)) }","sourceCodeStart":254,"sourceCodeEnd":290,"githubUrl":"https://github.com/tokio-rs/tokio/blob/625954f365727668cb02d04172b34f1149637728/tokio/src/signal/unix.rs#L254-L290","documentation":"signal_enable refuses to register a signal number that is <= 0 or is in signal_hook_registry::FORBIDDEN. These signals cannot be safely handled through the generic registry path (e.g. SIGKILL=9, SIGSTOP=19 on Linux cannot be caught). The error is returned as io::Error kind Other.","triggerScenarios":"Calling unix::signal(SignalKind::from_raw(n)) with n <= 0 or a forbidden value such as SIGKILL or SIGSTOP.","commonSituations":"Passing SignalKind::from_raw(0); trying to listen for SIGKILL/SIGSTOP; computing a signal number incorrectly and producing a non-positive value.","solutions":["Use a valid catchable signal: SignalKind::interrupt, SignalKind::terminate, SignalKind::hangup, etc.","Validate the raw number is > 0 and not SIGKILL/SIGSTOP before passing it.","Read signal_hook_registry::FORBIDDEN at startup to confirm your target signal is allowed.","Never attempt to handle SIGKILL/SIGSTOP — design shutdown around SIGTERM/SIGINT instead."],"exampleFix":"// before\nlet s = signal(SignalKind::from_raw(9))?; // SIGKILL refused\n// after\nlet s = signal(SignalKind::terminate())?; // SIGTERM","handlingStrategy":"validation","validationCode":"const FORBIDDEN: &[i32] = &[9 /*SIGKILL*/, 19 /*SIGSTOP*/];\nfn can_register(sig: i32) -> bool {\n    sig > 0 && !FORBIDDEN.contains(&sig)\n}\nif !can_register(num) { return Err(io::Error::new(io::ErrorKind::Other, \"refused\")); }\nsignal(SignalKind::from_raw(num))?","typeGuard":"fn is_catchable_signal(sig: i32) -> bool {\n    sig > 0 && sig != 9 && sig != 19\n}","tryCatchPattern":"match signal(SignalKind::from_raw(num)) {\n    Ok(s) => s,\n    Err(e) if e.to_string().contains(\"Refusing to register\") => return Err(e),\n    Err(e) => return Err(e),\n}","preventionTips":["Prefer named SignalKind helpers (interrupt, terminate, hangup).","Never attempt to handle SIGKILL/SIGSTOP.","Validate raw signal numbers > 0 before registering."],"tags":["signal","signal-handling","unix","validation","io-error"],"backgroundTag":null,"analyzedSha":"625954f365727668cb02d04172b34f1149637728","analyzedAt":"2026-08-11T17:46:45.378Z","contentChangedAt":"2026-08-11T17:46:45.378Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}