walkor/workerman · critical · RuntimeException
forkOneWorker fail
Error message
forkOneWorker fail
What it means
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.
Source
Thrown at src/Worker.php:1766
// Init Timer.
Timer::init(static::$globalEvent);
restore_error_handler();
static::setProcessTitle('WorkerMan: worker process ' . $worker->name . ' ' . $worker->getSocketName());
$worker->setUserAndGroup();
$worker->id = $id;
$worker->run();
// Main loop.
static::$globalEvent->run();
if (static::$status !== self::STATUS_SHUTDOWN) {
$err = new Exception('event-loop exited');
static::log($err);
exit(250);
}
exit(0);
} else {
throw new RuntimeException("forkOneWorker fail");
}
}
/**
* Get worker id.
*
* @param string $workerId
* @param int $pid
* @return false|int|string
*/
protected static function getId(string $workerId, int $pid): false|int|string
{
return array_search($pid, static::$idMap[$workerId]);
}
/**
* Set unix user and group for current process.
*View on GitHub (pinned to 1391112a61)
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
Example fix
# before
# 10 workers x count 50 = 500 procs, pod pids limit 512
# -> RuntimeException('forkOneWorker fail') while spawning
# after
# raise the pod pid limit to 1024 (K8s: kubelet podPidsLimit or namespace limitRange)
# or reduce footprint:
# $worker->count = 20; // 10 x 20 = 200 procs, fits under 512 Defensive patterns
Strategy: retry
Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Fork fail
- Bad remoteAddress
- Invalid protocol scheme '$scheme'
- class \Protocols\$scheme not exist
- Invalid protocol scheme '$scheme'
AI-assisted analysis of walkor/workerman@1391112a61 (2026-08-21).
Data as JSON: /api/errors/03ea2d1f07dcef94.
Report an issue: GitHub.