Docker Exit Code 137 (tested)
Exit code 137 means a container's main process was killed by SIGKILL (signal 9): 128 + 9 = 137. The most common cause by far is the Linux out-of-memory killer terminating the process because the container hit its memory limit — but any external SIGKILL, including a manual docker kill, produces the same code.
1. Reproduced: a real OOM kill
We ran a container with a 50 MB memory limit and had it allocate 300 MB inside Python:
docker run --name forever-oom-test -m 50m python:3-alpine python3 -c "
x = bytearray(300*1024*1024)
print('allocated')
"
echo "exit code: $?"
exit code: 137
Notice 'allocated' never printed — the process was killed mid-allocation, before it could reach that line.
2. Confirming it was the OOM killer, not a crash
Exit code 137 alone doesn't prove it was memory — a manual docker kill on a perfectly healthy container produces the identical code. docker inspect has a dedicated field that removes the ambiguity:
docker inspect forever-oom-test2 --format '{{.State.OOMKilled}} {{.State.ExitCode}} {{.State.Status}}'
true 137 exited
OOMKilled: true is the definitive signal. If it says false and you still see 137, something external sent the kill signal — check for a manual docker stop timeout (which escalates to SIGKILL) or an orchestrator (Kubernetes, Swarm) terminating the container.
3. docker ps confirms the same thing more casually
docker ps -a --filter name=forever-oom-test3 --format "{{.Names}}: {{.Status}}"
forever-oom-test3: Exited (137) Less than a second ago
docker logs on this same container returned nothing at all — another symptom worth recognizing: an OOM-killed process usually dies too abruptly to flush buffered output, so don't expect an error message in the application's own logs. The signal, not the app, is what killed it.
4. The fix: raise the memory limit, verified
We re-ran the identical script with the memory limit raised from 50m to 512m, enough for the 300 MB allocation to fit:
docker run --rm -m 512m python:3-alpine python3 -c "
x = bytearray(300*1024*1024)
print('allocated', len(x), 'bytes')
"
echo "exit code: $?"
allocated 314572800 bytes
exit code: 0
Same code, same image, only the -m value changed — and it completed cleanly with exit code 0.
5. If raising the limit isn't the right fix
Sometimes the container's memory need is supposed to be bounded, and the real bug is a leak or an unbounded allocation (e.g. loading an entire file into memory instead of streaming it). In that case, raising -m just delays the same kill at a larger input size. Treat OOMKilled: true as a prompt to check: does this process's expected memory use actually fit in the limit you intended, or is something growing unbounded that should be capped or streamed instead?
6. In Docker Compose and Kubernetes
The same mechanism applies under Compose (mem_limit: in the service definition) and Kubernetes (a Pod's container exceeding its resources.limits.memory gets OOMKilled by the kubelet, visible as OOMKilled in kubectl describe pod and reason OOMKilled in the container status) — same signal, same exit code 137, just surfaced through a different tool.
Frequently asked questions
Does exit code 137 always mean out of memory?
No. It always means SIGKILL (128+9), but we confirmed via docker inspect's OOMKilled field that this specifically distinguishes a memory kill (true) from any other SIGKILL, like a manual docker kill or a stop timeout (false).
Why didn't my app log an error before it died?
We observed this directly: docker logs on our OOM-killed container returned nothing. SIGKILL doesn't give the process a chance to catch the signal or flush output, unlike a graceful SIGTERM shutdown.
How do I know what memory limit to actually set?
Measure real usage under realistic load first (docker stats shows live memory use), then set -m with headroom above that measured peak, not a guess. We demonstrated the opposite failure mode: a limit set below real usage (50m vs a 300MB need) kills the container every time.
Is this different in Kubernetes?
The underlying mechanism is identical (the kernel OOM-killing a process that exceeds its cgroup memory limit) but Kubernetes surfaces it as reason: OOMKilled in kubectl describe pod rather than Docker's OOMKilled field directly.
What if OOMKilled is false but I still got 137?
Then something external sent SIGKILL deliberately: a manual docker kill, or docker stop escalating to SIGKILL after its grace period (10s default) expired without the process exiting on SIGTERM. Check for that first before assuming a memory problem.
Written with AI assistance. Measured on 2026-10-03 with Docker Engine on Linux, using a real memory-limited container (python:3-alpine) that was actually OOM-killed. Every exit code and status below is copy-pasted output, not paraphrased. PlainHeaders is our extension; Docker is free.