{"record":{"id":"03ea2d1f07dcef94","repo":"walkor/workerman","slug":"forkoneworker-fail","errorCode":null,"errorMessage":"forkOneWorker fail","messagePattern":"forkOneWorker fail","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"critical","filePath":"src/Worker.php","lineNumber":1766,"sourceCode":"            // Init Timer.\n            Timer::init(static::$globalEvent);\n\n            restore_error_handler();\n\n            static::setProcessTitle('WorkerMan: worker process  ' . $worker->name . ' ' . $worker->getSocketName());\n            $worker->setUserAndGroup();\n            $worker->id = $id;\n            $worker->run();\n            // Main loop.\n            static::$globalEvent->run();\n            if (static::$status !== self::STATUS_SHUTDOWN) {\n                $err = new Exception('event-loop exited');\n                static::log($err);\n                exit(250);\n            }\n            exit(0);\n        } else {\n            throw new RuntimeException(\"forkOneWorker fail\");\n        }\n    }\n\n    /**\n     * Get worker id.\n     *\n     * @param string $workerId\n     * @param int $pid\n     * @return false|int|string\n     */\n    protected static function getId(string $workerId, int $pid): false|int|string\n    {\n        return array_search($pid, static::$idMap[$workerId]);\n    }\n\n    /**\n     * Set unix user and group for current process.\n     *","sourceCodeStart":1748,"sourceCodeEnd":1784,"githubUrl":"https://github.com/walkor/workerman/blob/1391112a61d23020e11e7b89f17050f6cfaea431/src/Worker.php#L1748-L1784","documentation":"forkOneWorkerForLinux() spawns each worker child with pcntl_fork(); the else-branch (pid not > 0 and not 0, i.e. -1) throws this. The master could not create the worker process - OS-level fork failure, most commonly the process/PID limit (RLIMIT_NPROC or the container pids cgroup) or insufficient memory at fork time. It can hit at initial startup or when Workerman respawns a dead worker.","triggerScenarios":"Master forking many children (workers x count) until the process ceiling: e.g. 16 workers x 20 processes on a host with a low pids limit; respawn after workers die while the system is at the ceiling; cgroup pids.max reached because of a leak of grandchild processes.","commonSituations":"Kubernetes pods with default pid limits and high Worker->count; Docker --pids-limit set conservatively; leftover grandchild processes (spawned by workers) counting against the same cgroup; memory pressure refusing page-table copies.","solutions":["Raise the ceiling: ulimit -u, docker --pids-limit, or the K8s pod-level pids limit, sized for workers x count plus headroom","Audit runaway children with 'cat /sys/fs/cgroup/pids/pids.current' (or pids/pids.current in the cgroup dir) and kill leaks - worker-spawned subprocesses count against the same budget","Lower total processes: reduce Worker->count or the number of Worker instances so the app fits the limit"],"exampleFix":"# before\n# 10 workers x count 50 = 500 procs, pod pids limit 512\n# -> RuntimeException('forkOneWorker fail') while spawning\n\n# after\n# raise the pod pid limit to 1024 (K8s: kubelet podPidsLimit or namespace limitRange)\n# or reduce footprint:\n#   $worker->count = 20;  // 10 x 20 = 200 procs, fits under 512","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Budget processes as workers x count + grandchildren and set cgroup/ulimit limits above that","Reap or limit subprocesses spawned from workers; they share the same pids cgroup budget","Alert on fork failures so a respawn loop under an exhausted limit is caught early"],"tags":["php","workerman","fork","worker-processes","process-limit","cgroups"],"backgroundTag":"fork-failed","analyzedSha":"1391112a61d23020e11e7b89f17050f6cfaea431","analyzedAt":"2026-08-21T02:05:46.744Z","schemaVersion":2},"datasetVersion":"2026-08-21T03:17:12.404Z"}