{"record":{"id":"c8dddefce33927f2","repo":"facebook/flow","slug":"failed-to-spawn-init-thread","errorCode":null,"errorMessage":"failed to spawn init thread","messagePattern":"failed to spawn init thread","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"rust_port/crates/flow_server/src/standalone.rs","lineNumber":377,"sourceCode":"                        &init_socket_path,\n                    );\n                }));\n                if let Err(payload) = init_result {\n                    let panic_message = payload\n                        .downcast_ref::<&str>()\n                        .copied()\n                        .or_else(|| payload.downcast_ref::<String>().map(String::as_str))\n                        .unwrap_or(\"unknown panic payload\");\n                    eprintln!(\"Error: server initialization panicked: {}\", panic_message);\n                    cleanup_and_exit_with_code(\n                        &init_pids_path,\n                        &init_lock_path,\n                        &init_socket_path,\n                        1,\n                    );\n                }\n            })\n            .expect(\"failed to spawn init thread\");\n\n        let connection_slots = Arc::new(ConnectionSlots::new());\n\n        for stream in listener.incoming() {\n            match stream {\n                Ok(stream) => {\n                    if let Err(e) = stream.set_nodelay(true) {\n                        eprintln!(\"Error setting TCP_NODELAY on client connection: {}\", e);\n                    }\n                    let Some(slot_guard) = connection_slots.try_acquire() else {\n                        eprintln!(\"Refusing connection: too many concurrent clients\");\n                        drop(stream);\n                        continue;\n                    };\n                    let state = state.clone();\n                    let options = self.options.dupe();\n                    let committed_heap = self.committed_heap.dupe();\n                    let pool_workers = self.pool.num_workers();","sourceCodeStart":359,"sourceCodeEnd":395,"githubUrl":"https://github.com/facebook/flow/blob/f88ac94bcf6992f5d5a158854d94613ebb92c6e6/rust_port/crates/flow_server/src/standalone.rs#L359-L395","documentation":"The standalone server performs first-time initialization on a dedicated thread and expects std::thread::Builder::spawn to succeed ('failed to spawn init thread', rust_port/crates/flow_server/src/standalone.rs:377). The surrounding code carefully handles panics raised inside the init thread; this expect only covers failure to create the thread at all, which is an OS-level refusal: thread/process limits or memory for the thread's stack. When it fires, the accept-loop setup aborts and the server never starts.","triggerScenarios":"Server startup on a host that has hit RLIMIT_NPROC or cgroup pids.max, or with insufficient memory to map the init thread's stack, typically when many flow servers or other processes already consume the thread budget.","commonSituations":"Shared CI hosts; containers with pids limits; editors opening multiple projects each starting a flow server; systemd user-session UserTasksMax limits kicking in.","solutions":["Raise ulimit -u / container pids.max / UserTasksMax, or reduce the number of concurrent flow servers on the host","Free memory so the init thread's stack can be mapped, then restart","Replace the expect with the same cleanup_and_exit_with_code path used for init panics, logging the io::Error from spawn","Start the server via the monitor daemon, which reports startup failures structurally instead of crashing silently"],"exampleFix":"// before\n.expect(\"failed to spawn init thread\");\n\n// after\nmatch builder.spawn(move || { ... }) {\n    Ok(_t) => {}\n    Err(e) => {\n        eprintln!(\"Error: cannot spawn init thread: {e}\");\n        cleanup_and_exit_with_code(&init_pids_path, &init_lock_path, &init_socket_path, 1);\n    }\n}","handlingStrategy":"validation","validationCode":"// Cheap headroom check before server start\nlet threads: usize = std::fs::read_to_string(\"/proc/self/status\")\n    .ok()\n    .and_then(|s| s.lines().find(|l| l.starts_with(\"Threads:\")).and_then(|l| l.split_whitespace().nth(1).and_then(|n| n.parse().ok())))\n    .unwrap_or(0);\nif threads + 4 >= thread_limit() {\n    eprintln!(\"thread headroom too low for server init; raise limits\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Raise pids.max / ulimit -u / UserTasksMax for service accounts running flow","One flow server per project; avoid stacking many servers in one cgroup","Watch for 'cannot create thread' in dmesg as an early warning"],"tags":["thread-spawn","resource-limits","server-startup","initialization","panic"],"backgroundTag":"thread-spawn-failed","analyzedSha":"f88ac94bcf6992f5d5a158854d94613ebb92c6e6","analyzedAt":"2026-08-20T10:41:37.992Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}