ENOMEM is the operating system saying "not enough memory". Node.js passes it through from system calls, so you see errors like these:
Error: spawn ENOMEM
Error: ENOMEM: not enough memory, read
fork: retry: Cannot allocate memory
Error: Cannot allocate memory
This is different from FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory, which is V8's own limit on the JavaScript heap. For that case, read Node heap out of memory. ENOMEM means the machine or container has no memory (or address space) left for the request, regardless of how much your JavaScript uses. The usual culprits are child_process calls, native add-ons, large buffers or a host with too little RAM and no swap.
Step 1: see how much memory the system really has
free -m
cat /proc/meminfo | grep -E "MemTotal|MemAvailable|SwapTotal|SwapFree|CommitLimit|Committed_AS"
ps aux --sort=-%mem | head -n 10
Look at available memory rather than "free". If MemAvailable is near zero and swap is absent or full, you are simply out of memory. A small VPS with 512 MB or 1 GB of RAM running a build, a database and a Node app is a classic case.
Step 2: check whether the OOM killer was involved
If a process vanished at the same moment, the kernel may have killed it:
sudo dmesg -T | grep -iE "out of memory|oom-kill|killed process"
sudo journalctl -k --since "1 hour ago" | grep -i oom
A line such as Out of memory: Killed process 4127 (node) confirms it. That is the same story as exit code 137 in containers; see Docker container exit code 137.
Step 3: check container and cgroup limits
Inside Docker or Kubernetes, the limit that matters is the container's, not the host's:
docker stats --no-stream
docker inspect --format '{{.HostConfig.Memory}}' mycontainer
cat /sys/fs/cgroup/memory.max # cgroup v2
cat /sys/fs/cgroup/memory/memory.limit_in_bytes # cgroup v1
In Kubernetes, compare resources.limits.memory with actual use in kubectl top pod. A limit of 256Mi that includes a spawned ffmpeg or headless browser will be exceeded quickly. Remember that Node's heap is only one part of memory use; native buffers, child processes and the runtime add to the total.
Step 4: fix the cause
Spawning child processes. spawn ENOMEM and fork: Cannot allocate memory happen when creating a child process fails. Common triggers: running many parallel child_process.exec calls, image or PDF conversion, headless Chrome. Limit concurrency with a queue (for example p-limit), reuse long-lived workers, and prefer spawn with streamed output over exec, which buffers output in memory.
Large data in memory. Reading whole files with fs.readFile, loading huge JSON, or collecting streams into a Buffer can exhaust memory outside the V8 heap. Use streams:
const { pipeline } = require('stream/promises');
await pipeline(fs.createReadStream(src), transform, fs.createWriteStream(dest));
Memory leaks. Memory that grows steadily until restart points at a leak: unbounded caches, listeners never removed, global arrays. Capture heap snapshots with node --inspect and compare, or use --heapsnapshot-signal=SIGUSR2 and send the signal at intervals.
Not enough RAM. Add swap as a safety net on small servers, or resize the instance. A swap file looks like this:
sudo fallocate -l 2G /swapfile && sudo chmod 600 /swapfile
sudo mkswap /swapfile && sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
Swap keeps processes alive but is far slower than RAM, so treat it as a cushion, not a fix for undersized hosts.
Overcommit settings. With vm.overcommit_memory=2 the kernel refuses allocations beyond CommitLimit, which can cause ENOMEM while RAM looks free. Check sysctl vm.overcommit_memory and the Committed_AS figure. Change it only if you understand the effect on all workloads.
Memory-hungry build steps. npm install and bundlers can spike. Build in CI or a larger machine, then ship the artifact.
Step 5: set limits so one failure does not take down the host
Cap memory per service (MemoryMax= in a systemd unit, or container limits), restart on failure, and keep Node's heap limit below the container limit so you get a clear error instead of a kill. For example, if the container has 1 GB, node --max-old-space-size=768 app.js leaves headroom for buffers and the runtime.
Verify
Watch free -m and docker stats during the operation that failed. Memory should stay under your limit with headroom, and dmesg should show no new OOM lines. Put the app under an अपटाइम मॉनिटर so a crash-restart loop is noticed quickly, and use the वेबसाइट हेल्थ चेक to look at the response from outside.
अगले कदम
- Compare with Node heap out of memory.
- Read Node EMFILE too many open files for a different resource limit.
- Use why is my website down when the app is unreachable.
- Review PHP allowed memory size exhausted for the PHP equivalent.
सामान्य प्रश्न
Is ENOMEM the same as JavaScript heap out of memory?
No. Heap out of memory is V8's limit on the JS heap. ENOMEM is the operating system refusing to hand over more memory for a system call.
Why does it only happen when I spawn a process?
Starting a child process requires the system to reserve memory for it. If the machine is low on memory, or overcommit is restricted, that request fails first.
Will more swap solve it?
It can prevent immediate failures on small servers, but it is slow. Fix memory use or resize the machine for a lasting solution.
How do I know if the kernel killed my app?
Check dmesg or the kernel journal for Out of memory: Killed process. Containers also show exit code 137.
Get notified when this fix updates
Plus occasional practical tips on uptime and monitoring, nothing else. Unsubscribe anytime.
यह पेज सामान्य जानकारी है, जिसे हमारी संपादकीय टीम ने लिखा है और दस्तावेज़ीकरण बदलने पर अपडेट किया जाता है। सर्वर और प्रदाता अलग-अलग होते हैं, इसलिए बदलाव पहले सुरक्षित तरीके से जाँचें। देखें: संपादकीय नीति और अस्वीकरण.