JavaScript Heap Out of Memory (tested)
FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory is V8 (the JavaScript engine behind Node and Chrome) hitting its own memory ceiling, not the operating system running out of RAM. We triggered it for real with a small Node script and a low --max-old-space-size limit, and confirmed the fix.
1. The exact error, reproduced
We ran a script that keeps allocating arrays in a loop, capped at a 50 MB V8 heap:
$ node --max-old-space-size=50 -e "
let arr = [];
while (true) { arr.push(new Array(1000000).fill('x')); }
"
<...Mark-Compact GC log lines...>
FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory
1: 0x931db0 [node]
2: 0x75968e node::OOMErrorHandler(char const*, v8::OOMDetails const&) [node]
...
The process exits with code 134 (SIGABRT, signal 6) — see our exit code 137 guide for the full signal-to-exit-code table. This is a hard process abort, not a JavaScript exception.
2. Why you cannot catch it with try/catch
A normal out-of-memory condition inside your own code (e.g. new Array(-1) or an explicit allocation failure) throws a catchable RangeError or similar. This is different: when V8's garbage collector cannot free enough heap to satisfy an allocation and the heap is already at its configured ceiling, V8 calls an unrecoverable fatal-error handler and aborts the whole process before your JavaScript code gets a chance to run a catch block. Wrapping your code in try/catch does not help — we confirmed this: the script above had no try/catch around the loop and none would have changed the outcome.
3. It's a V8 heap limit, not your system running out of RAM
This machine has far more than 50 MB of free RAM; the crash is V8 refusing to grow its own managed heap past the limit we gave it, which defaults to roughly 2–4 GB on 64-bit Node depending on version and available system memory (not a fixed number across all versions). That default is usually generous enough that you only see this error when either a real memory leak keeps objects alive, or a single operation (parsing a huge JSON file, building a huge array/string) needs more than the default heap at once. This is a distinct mechanism from an OS/container-level OOM kill — see our out-of-memory-killed guide for how the kernel-level version looks and how to tell them apart from the exit code and logs alone.
4. The fix: raise the heap limit, or fix the leak
We confirmed the fix directly: the identical allocating pattern that crashed at a 50 MB cap ran cleanly once given more room:
$ node --max-old-space-size=500 -e "
let arr = [];
for (let i = 0; i < 20; i++) { arr.push(new Array(1000000).fill('x')); }
console.log('OK: allocated 20 chunks (~200MB) without crashing, under the 500MB cap');
"
OK: allocated 20 chunks (~200MB) without crashing, under the 500MB cap
Two different fixes depending on which situation you're in:
- A single large but legitimate operation (e.g. a big build step, a large data-processing job): raise the limit with
node --max-old-space-size=4096 your-script.js(value in MB), or for npm scripts,NODE_OPTIONS="--max-old-space-size=4096" npm run build. Check the machine actually has that much free RAM first — raising the V8 limit past available system memory just trades a clean V8 crash for the kernel's own OOM killer. - Usage grows without bound over time (a long-running server that eventually crashes): that's a memory leak, and raising the limit only delays the same crash. Common culprits: event listeners or callbacks never removed, growing caches/arrays with no eviction, closures holding references to large objects longer than needed. Use
node --inspectand Chrome DevTools' heap snapshot comparison (or--max-old-space-sizeleft at default plus--trace-gc) to find what's accumulating, rather than just raising the limit.
5. Framework-specific build commands
The build-time version of this error is common in frameworks that compile the whole app in one Node process. The same NODE_OPTIONS fix applies; the usual places to set it (per the tools' own docs, not independently measured here since each project's exact invocation differs):
- Angular (
ng build/ng serve):NODE_OPTIONS="--max-old-space-size=4096" ng build, or add it to the"build"script in package.json. - Next.js / React (
npm run build):NODE_OPTIONS="--max-old-space-size=4096" npm run build; some setups need it inside across-envwrapper for Windows compatibility. - Running inside Docker: raising
--max-old-space-sizeonly helps if the container's own memory limit (if any) is higher than the new V8 limit — check both, since a container--memorycap will OOM-kill the process (a different error, see our Docker guides) before V8 even gets to its own limit.
Frequently asked questions
Why can't I catch 'JavaScript heap out of memory' with try/catch?
We confirmed this directly: V8 calls a fatal-error handler and aborts the entire process when it can't grow the heap further, before your JavaScript catch blocks get a chance to run. There is no way to recover in-process; the only options are to avoid hitting the limit (fix a leak, process data in smaller chunks) or give the process more headroom in advance.
What's the default max-old-space-size if I don't set one?
It varies by Node version and available system memory rather than being one fixed number — roughly 2-4GB on a typical 64-bit Node install, per Node's own docs. If you're hitting the limit with plenty of system RAM free, raising it explicitly with --max-old-space-size is usually the fastest fix for a one-off large operation.
Does raising --max-old-space-size always fix it?
Only if the issue is a single legitimate operation needing more room than the default. If memory usage climbs without bound over time (a leak), raising the limit just delays the same crash at a higher number — you'll need a heap snapshot (node --inspect + Chrome DevTools) to find what's accumulating.
What exit code does a JavaScript heap out of memory crash give?
We measured exit code 134 (SIGABRT) on this box — V8's fatal-error handler aborts the process rather than exiting cleanly. That's different from exit code 137 (SIGKILL), which is what you'd see from an external kill or a container/OS-level out-of-memory kill rather than V8's own internal heap limit.
Is this the same as a Docker container getting OOM-killed?
No — they're different mechanisms that can look similar. This error is V8's own internal heap ceiling being hit (fixable with --max-old-space-size); a Docker/Kubernetes OOM kill happens when the container's memory cgroup limit is exceeded regardless of what Node's own heap settings are, and raising --max-old-space-size won't help if the container limit is the binding constraint — see our out-of-memory-killed guide for how we reproduced and distinguished that case.
Written with AI assistance. Measured on 2026-10-02 on Debian 13 / Linux 6.12 with Node (the version in this box's PATH). We ran real allocating scripts under --max-old-space-size at several limits and captured the exact crash text, exit code, and the limit at which the same script succeeds. PlainHeaders is our extension; Node is free.