What do Kubernetes container exit codes mean, and how do you use them for troubleshooting?
Quick Answer
Exit code 0 means success. Exit 1 means general application error (check logs). Exit 137 means OOMKilled or SIGKILL (container exceeded memory limit). Exit 139 means segmentation fault. Exit 143 means graceful termination via SIGTERM. Exit 127 means command not found in the container image.
Detailed Answer
Think of a doctor checking vital signs. Each number tells a different story — blood pressure of 120 is normal, 200 is a crisis. Container exit codes work the same way: the number instantly tells you the category of failure before you even look at the logs.
Exit code 0 is the only success code — the container completed its work normally. This is expected for Jobs and init containers. For long-running services, exit 0 means the process chose to stop, which might indicate a graceful shutdown from SIGTERM or an application bug that causes premature exit.
Exit code 1 is a generic application error. The process encountered an unhandled exception, a failed assertion, or a startup error. Check the container logs with kubectl logs --previous to find the stack trace or error message. Common causes include missing environment variables, unreachable databases, malformed configuration files, or application bugs.
Exit code 137 is critical — it means the container was killed by SIGKILL (signal 9). In Kubernetes, this almost always means OOMKilled: the container exceeded its memory limit and the Linux kernel's Out-Of-Memory killer terminated it. Check with kubectl describe pod to confirm OOMKilled in the termination reason. The fix is either increasing the memory limit or fixing the memory leak in the application. Exit 137 can also occur when kubelet kills a container that fails its liveness probe.
At production scale, teams build dashboards that track exit codes by service. A spike in exit 137 across multiple pods signals a memory issue affecting the entire service. Exit 139 (segfault) spikes after a deployment indicate a binary compatibility issue or a code bug. Exit 143 during rolling updates is normal (graceful shutdown). Monitoring exit code patterns, not just individual pod failures, reveals systemic issues.
The non-obvious gotcha is that exit codes above 128 indicate the process was killed by a signal: exit code = 128 + signal number. So 137 = 128 + 9 (SIGKILL), 143 = 128 + 15 (SIGTERM), 139 = 128 + 11 (SIGSEGV). If you see exit code 134 (128 + 6 = SIGABRT), the process called abort() — often from a failed assertion or a detected heap corruption. Knowing this formula lets you decode any exit code instantly.