{"record":{"id":"875c300fde62d0e4","repo":"cloudflare/pingora","slug":"failed-to-build-tokio-runtime-for-parent-signal-wa","errorCode":null,"errorMessage":"failed to build tokio runtime for parent signal wait","messagePattern":"failed to build tokio runtime for parent signal wait","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"pingora-core/src/server/daemon.rs","lineNumber":258,"sourceCode":"            \"Waiting up to {:?} for daemon to signal readiness via SIGUSR1\",\n            timeout\n        );\n\n        wait_for_ready_or_exit(&conf.pid_file, timeout);\n    }\n\n    process::exit(0);\n}\n\n/// Build a single-threaded tokio runtime for the parent's signal wait loop.\n///\n/// The parent process is short-lived and only needs to wait for a signal and check the pid file.\n/// A current-thread runtime avoids spawning worker threads in a process that is about to exit.\nfn build_parent_runtime() -> tokio::runtime::Runtime {\n    tokio::runtime::Builder::new_current_thread()\n        .enable_all()\n        .build()\n        .expect(\"failed to build tokio runtime for parent signal wait\")\n}\n\n/// Wait for the daemon grandchild to send `SIGUSR1`, up to `timeout`.\n///\n/// Uses a local tokio runtime with [`tokio::signal::unix`] to listen for `SIGUSR1` instead of\n/// raw signal handlers and polling loops. The daemon's PID is checked periodically via the pid\n/// file — if the process exits before signaling, the parent aborts.\n///\n/// Exits the process directly:\n/// - exit code 0 if `SIGUSR1` is received (daemon is ready).\n/// - exit code 1 if `timeout` elapses (daemon took too long).\n/// - exit code 1 if the pid file exists and the process is no longer running.\nfn wait_for_ready_or_exit(pid_file: &str, timeout: Duration) {\n    let rt = build_parent_runtime();\n    let pid_file = pid_file.to_owned();\n\n    rt.block_on(async move {\n        use tokio::signal::unix::{signal, SignalKind};","sourceCodeStart":240,"sourceCodeEnd":276,"githubUrl":"https://github.com/cloudflare/pingora/blob/0046038bd402bc82912da862dadf9a479f31e9f1/pingora-core/src/server/daemon.rs#L240-L276","documentation":"During daemonization, pingora's short-lived parent process builds a single-threaded (current_thread) tokio runtime to wait for the daemon's readiness signal. This expect fires when tokio's runtime builder returns Err — in practice an OS-level resource problem: creating the IO/timer drivers (epoll/eventfd) or runtime resources failed under restrictive limits or sandboxes, not application logic.","triggerScenarios":"Running the daemonize path (wait_for_ready_or_exit -> build_parent_runtime) where Builder::new_current_thread().enable_all().build() fails: epoll/eventfd/timerfd creation blocked, or the process is out of file descriptors / memory for runtime resources.","commonSituations":"Containers with very low ulimit -n or cgroup pids.max; seccomp profiles (Docker default+strictening, gVisor, nsjail) blocking epoll_create1/eventfd; fd leaks accumulated before daemonization.","solutions":["Check and raise limits: ulimit -n, ulimit -u, and the cgroup pids limit for the process","Run the same binary foreground (--daemon off / no daemon) to confirm it works outside the restricted environment","Inspect seccomp/sandbox policy for syscalls tokio needs (epoll_create1, eventfd, timerfd_create) and allow them","Check lsof / /proc/<pid>/fd for fd leaks before the daemon step"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Pre-flight in the target environment: can we even build a runtime?\nfn tokio_runtime_buildable() -> bool {\n    tokio::runtime::Builder::new_current_thread()\n        .enable_all()\n        .build()\n        .is_ok()\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Set sane RLIMIT_NOFILE/RLIMIT_NPROC in the supervisor or container spec","Include a startup smoke test that builds a tokio runtime inside your production image","Prefer foreground execution under systemd over pingora daemon mode in restricted sandboxes"],"tags":["rust","pingora","tokio","runtime","daemon","resource-limits","panic"],"backgroundTag":"runtime-initialization-failed","analyzedSha":"0046038bd402bc82912da862dadf9a479f31e9f1","analyzedAt":"2026-08-16T21:33:22.341Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}