Blog

How to Catch Docker OOM Exit 137 in Node.js Containers

Exit 137 means the kernel killed the container. Node never runs a catch block. Here is the root cause, and how to keep the command and a GitHub draft.

2026-10-23 · 3 min read · AethelLayer

What you see

The container stops. docker inspect shows "OOMKilled": true. The process status is 137, which is 128 plus SIGKILL (9). The Node process does not get an uncaughtException handler call. SIGKILL is not catchable.

The terminal often looks like a hang, then nothing. Charts for the API can stay green because the request never reached the server.

Root cause

The cgroup memory limit is lower than the Node heap plus native memory. A login or index step loads a large payload, V8 grows the old space, and the kernel OOM killer sends SIGKILL. Exit code 137 is the shell's report of that signal. Raising --max-old-space-size past the container limit makes the kill more likely, not less.

What to keep

  • The exact argv, including flags like --env staging.
  • Exit code 137 and the OOM classification.
  • The stack you still have from the last log lines, if the runtime flushed them.
  • One note from the person who ran it: what they were trying to do.

Wire the probe

Install nothing global. The command below prints the CLI wrap, the Express middleware, and the Next.js instrumentation hook.

bashnpx --yes @aethellayer/sdk init

Wrap the failing command so stdout and stderr are kept when the exit code is fatal:

bashnpx --yes @aethellayer/sdk run -- node server.js

Exit 137 is classified as ERR_DOCKER_OOM. AethelLayer writes a local log and, when it can see a GitHub remote, prints a draft issue URL. It does not file the issue. You press send.

Fix the container

Set the memory limit above the heap you actually need, or lower the heap so it dies with a catchable V8 error instead of SIGKILL. Keep the probe on the CLI so the next 137 still leaves a draft.

Capture the failure before they leave

Install the probe. It drafts the GitHub issue. You still send it.

npx --yes @aethellayer/sdk init