Node.js "ENOMEM: not enough memory" / "Cannot allocate memory" in CI
The kernel refused a memory request - ENOMEM. Unlike a V8 heap error, this is the OS saying there is no memory to give, often when Node tries to allocate a buffer or spawn a child process on a tight runner.
What this error means
A step fails with ENOMEM or spawn ENOMEM, sometimes while forking a worker or child process rather than during your own allocation. It is environment-specific - the same code passes on a runner with more memory.
Error: spawn ENOMEM
at ChildProcess.spawn (node:internal/child_process:421:11)
errno: -12,
code: 'ENOMEM',
syscall: 'spawn'Common causes
The runner is out of physical memory
A memory-hungry build plus parallel test workers exhausts the runner’s RAM. The next allocation (or fork, which briefly needs to copy the address space) is refused with ENOMEM.
Forking many child processes
Spawning a worker per CPU on a constrained runner can momentarily require more memory than is free, so spawn itself fails with ENOMEM even if steady-state usage would fit.
How to fix it
Reduce peak memory and parallelism
Lower worker counts so fewer processes are resident at once, and cap the V8 heap so a single process cannot balloon.
# fewer workers
jest --maxWorkers=2
# bound the heap
NODE_OPTIONS=--max-old-space-size=2048 npm run buildUse a runner with more memory
- Move the job to a larger runner class when the workload genuinely needs it.
- Add swap on self-hosted runners as a cushion against spikes.
- Split a giant build into smaller steps that each fit in memory.
How to prevent it
- Size the runner to the build’s real memory needs.
- Limit test/worker parallelism on constrained runners.
- Cap the V8 heap below available memory so one process can’t exhaust the box.