{"record":{"id":"7061d86b744d70bf","repo":"walkor/workerman","slug":"fork-fail","errorCode":null,"errorMessage":"Fork fail","messagePattern":"Fork fail","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"critical","filePath":"src/Worker.php","lineNumber":1438,"sourceCode":"            SIGUSR2 => 'SIGUSR2',\n            SIGIOT => 'SIGIOT',\n            SIGIO => 'SIGIO',\n            default => $signal,\n        };\n    }\n\n    /**\n     * Run as daemon mode.\n     */\n    protected static function daemonize(): void\n    {\n        if (!static::$daemonize || DIRECTORY_SEPARATOR !== '/') {\n            return;\n        }\n        umask(0);\n        $pid = pcntl_fork();\n        if (-1 === $pid) {\n            throw new RuntimeException('Fork fail');\n        } elseif ($pid > 0) {\n            exit(0);\n        }\n        if (-1 === posix_setsid()) {\n            throw new RuntimeException(\"Setsid fail\");\n        }\n        // Fork again avoid SVR4 system regain the control of terminal.\n        $pid = pcntl_fork();\n        if (-1 === $pid) {\n            throw new RuntimeException(\"Fork fail\");\n        } elseif (0 !== $pid) {\n            exit(0);\n        }\n    }\n\n    /**\n     * Redirect standard output to stdoutFile.\n     *","sourceCodeStart":1420,"sourceCodeEnd":1456,"githubUrl":"https://github.com/walkor/workerman/blob/1391112a61d23020e11e7b89f17050f6cfaea431/src/Worker.php#L1420-L1456","documentation":"When starting in daemon mode (-d/--daemon), Worker::daemonize() forks to detach from the terminal. pcntl_fork() returned -1, meaning the OS refused to create the process - typically because a process limit was hit (RLIMIT_NPROC, cgroup pids.max in containers) or memory could not be allocated for the child.","triggerScenarios":"Running 'php start.php start -d' on a host already at its user process limit; Docker/Kubernetes with a low --pids-limit or pod pids cgroup ceiling; fork attempted while memory overcommit refuses the copy.","commonSituations":"Shared servers with tight ulimit -u; containers with default pids limits while the app forks many workers; CI environments restricting process creation; systems recovering from a fork-bomb incident with lowered limits.","solutions":["Raise the limits: 'ulimit -u 65535' (or the systemd/container equivalent, e.g. docker run --pids-limit=-1 or a higher K8s pid limit)","Count actual usage with 'ps -eLf | wc -l' or the cgroup pids.current file to see what is exhausting the ceiling","As a workaround, run without -d (foreground) to isolate whether the daemonize fork specifically is the blocker, and reduce total worker processes"],"exampleFix":"# before\nphp start.php start -d   # master at nproc/pids limit -> RuntimeException('Fork fail')\n\n# after\nulimit -u 65535            # or raise docker --pids-limit / k8s pod pids limit\nphp start.php start -d","handlingStrategy":"validation","validationCode":"$soft = posix_getrlimit(); // before starting with -d\nif (isset($soft['RLIMIT_NPROC']) && $soft['RLIMIT_NPROC'] !== 'unlimited' && $soft['RLIMIT_NPROC'] < 1024) {\n    fwrite(STDERR, \"RLIMIT_NPROC={$soft['RLIMIT_NPROC']} is low; fork may fail - raise it before daemonizing\\n\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Provision ulimit -u / container pids limits with headroom for all worker processes plus the two daemonize forks","Set process ceilings in deployment manifests, not by trial at runtime"],"tags":["php","workerman","daemonize","fork","process-limit","posix"],"backgroundTag":"fork-failed","analyzedSha":"1391112a61d23020e11e7b89f17050f6cfaea431","analyzedAt":"2026-08-21T02:05:46.744Z","schemaVersion":2},"datasetVersion":"2026-08-21T03:17:12.404Z"}