Finding a container's exit code
docker ps -a
# STATUS column: "Exited (1) 2 minutes ago"
docker inspect --format='{{.State.ExitCode}}' <container>The convention: 128 + signal number
Exit codes above 128 generally mean the process didn't exit on its own -- it was killed by a signal, and the code is 128 + signal number. 137 is 128 + 9 (SIGKILL), 143 is 128 + 15 (SIGTERM), 139 is 128 + 11 (SIGSEGV). Codes below 128 come from the application itself calling exit() with that value, directly or indirectly.
Common codes
Success
The main process exited cleanly. Nothing to debug.
Generic application error
The most common "something in my code crashed" code -- an unhandled exception, an uncaught promise rejection, a script that called exit(1) on its own error path.
Misuse of a shell built-in
Usually from a shell script's own exit 2, or incorrect arguments to a shell built-in -- check CMD/ENTRYPOINT if it's a shell script, not your application code.
Command found but not executable
The entrypoint exists but can't be run -- almost always a missing execute bit (chmod +x) on a COPYed script, or trying to "run" a plain text/config file.
Command not found
CMD/ENTRYPOINT references a binary that isn't in this image -- a typo, or a binary your base image genuinely doesn't have (common when switching from a full image like node:22 to node:22-alpine, which is missing many packages the full image ships).
SIGKILL (128 + 9)
Most often the OOM killer ending the process for exceeding its memory limit. Also happens if docker stop's grace period expired and Docker force-killed it.
SIGSEGV (128 + 11)
A segmentation fault in a compiled binary or native addon -- a real bug, or an architecture/ABI mismatch (for instance, an amd64-only native dependency running under QEMU emulation on arm64).
SIGTERM (128 + 15)
The normal signal docker stop sends. Often completely expected -- but if it happened faster than your app could clean up, see graceful shutdown below.
Confirming an OOM kill
Exit code 137 can come from a real OOM kill or from a force-kill after a stop timeout -- don't guess which, ask directly:
docker inspect <container> --format='{{.State.OOMKilled}}'If that's true, the fix is raising the container's memory limit or finding what's actually using that much memory -- see resource limits.
Graceful shutdown and exit code 143
A clean docker stop is expected to end in 143 -- that's just confirmation the process received and handled SIGTERM. If instead the process never gets the chance to shut down before being force-killed, see graceful shutdown for why that happens and how STOPSIGNAL and the exec form of CMD affect it.
In Kubernetes
A Pod surfaces a container's exit code indirectly, through its own status reasons -- CrashLoopBackOff, OOMKilled, Error versus Completed. See Kubernetes troubleshooting for how these line up with the codes on this page.