{"record":{"id":"b6be42ad6725c5de","repo":"sebastianbergmann/phpunit","slug":"unable-to-spawn-worker-process","errorCode":null,"errorMessage":"Unable to spawn worker process","messagePattern":"Unable to spawn worker process","errorType":"exception","errorClass":"PHPUnit\\Util\\PHP\\PhpProcessException","httpStatus":null,"severity":"error","filePath":"src/Util/PHP/JobRunner.php","lineNumber":223,"sourceCode":"        } else {\n            $pipeSpec = [\n                0 => ['pipe', 'r'],\n                1 => ['pipe', 'w'],\n                2 => ['pipe', 'w'],\n            ];\n        }\n\n        $process = proc_open(\n            $this->buildCommand($job, $temporaryFile),\n            $pipeSpec,\n            $pipes,\n            null,\n            $environmentVariables,\n        );\n\n        if (!is_resource($process)) {\n            // @codeCoverageIgnoreStart\n            throw new PhpProcessException(\n                'Unable to spawn worker process',\n            );\n            // @codeCoverageIgnoreEnd\n        }\n\n        Facade::emitter()->childProcessStarted($job->reason());\n\n        return new RunningJob($process, $pipes, $mergedOutputStream, $temporaryFile);\n    }\n\n    /**\n     * @return non-empty-list<string>\n     */\n    private function buildCommand(Job $job, ?string $file): array\n    {\n        $runtime     = new Runtime;\n        $command     = [PHP_BINARY];\n        $phpSettings = $job->phpSettings();","sourceCodeStart":205,"sourceCodeEnd":241,"githubUrl":"https://github.com/sebastianbergmann/phpunit/blob/f123cdb2a2d49f15025794166cfed8bda8627dd2/src/Util/PHP/JobRunner.php#L205-L241","documentation":"JobRunner::startProcess() spawns the child PHP process with proc_open(); when proc_open() does not return a resource it throws PhpProcessException('Unable to spawn worker process'). The job code was already written and the pipes prepared — only the actual process creation failed. Typical causes are an invalid or non-executable PHP binary, proc_open being disabled, or OS-level resource limits.","triggerScenarios":"Running tests in separate processes when the PHP CLI binary used for children does not exist or is not executable, proc_open is listed in disable_functions, the process/fork limit (ulimit, cgroups PIDs controller) is hit, or a container seccomp/apparmor profile blocks process creation.","commonSituations":"Docker/production-derived images where the php binary lives at a different path than PHP_BINARY reports; shared hosting with proc_open disabled for security; CI containers with a low pids limit; memory exhaustion preventing fork.","solutions":["Confirm the same PHP binary works where PHPUnit runs: `php -v` and `ls -l $(which php)`; fix PATH or install php-cli","Check `php -i | grep disable_functions` for proc_open and have it removed from disable_functions (or switch to a host that allows it)","Raise pid/fork limits (ulimit -u, container pids limit) or reduce parallel child usage","If the sandbox forbids spawning processes, drop process isolation for those tests"],"exampleFix":"# before\n$ php -r 'var_dump(function_exists(\"proc_open\"));' # false\n$ vendor/bin/phpunit --process-isolation\n# PhpProcessException: Unable to spawn worker process\n\n# after: enable proc_open (remove it from disable_functions in php.ini), then\n$ vendor/bin/phpunit --process-isolation","handlingStrategy":"try-catch","validationCode":"if (!function_exists('proc_open')) {\n    throw new RuntimeException('proc_open is disabled; process isolation unavailable');\n}\nif (PHP_BINARY === false || !is_executable(PHP_BINARY)) {\n    throw new RuntimeException('PHP CLI binary missing or not executable');\n}","typeGuard":null,"tryCatchPattern":"use PHPUnit\\Util\\PHP\\PhpProcessException;\n\ntry {\n    $runner->start($job);\n} catch (PhpProcessException $e) {\n    if ($e->getMessage() === 'Unable to spawn worker process') {\n        // report environment problem; do not retry blindly\n        throw new RuntimeException('Check PHP_BINARY, proc_open and pid limits', 0, $e);\n    }\n    throw $e;\n}","preventionTips":["Prefer `php -v` checks in the same image that runs PHPUnit to validate PHP_BINARY early","Keep proc_open off disable_functions in CI images; document it as a hard requirement for process isolation","Raise cgroup pids limits / ulimit -u when running many parallel child processes","When the sandbox cannot spawn processes, mark those tests to run without isolation"],"tags":["phpunit","proc-open","process-isolation","environment","disable-functions"],"backgroundTag":"process-spawn-failed","analyzedSha":"f123cdb2a2d49f15025794166cfed8bda8627dd2","analyzedAt":"2026-08-23T01:20:58.058Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}