US Edition Austin, TX UTC 00:00:00

Exit code 137, 139, 143 and other container exit codes explained

What container exit codes 137, 139, 143, 125-127 and 255 mean in Docker, Kubernetes and ECS, and how to confirm OOMKilled, SIGTERM or a segfault.

Exit code 137 means the container's main process was killed with SIGKILL, signal 9: runtimes report a death by signal as 128 plus the signal number. The usual sender is the Linux OOM killer enforcing a memory limit, but an expired stop timeout or a forced kill also gives 137, so check the termination reason before raising memory. Exit code 143 is SIGTERM (128 + 15), normally a requested shutdown, and 139 is SIGSEGV (128 + 11), a crash inside the process.

How to decode any container exit code

A container's exit code is the exit status of its main process, PID 1 inside the container. Three rules cover almost every value:

  • Low values are chosen by the program. Only the lowest byte of the value passed to exit() reaches the parent (exit(3)), so exit(-1) shows up as 255.
  • Values above 128 are usually 128 plus a signal number. The Bash manual documents this convention, and both runc and containerd apply the same 128 offset. For x86 and ARM, signal(7) lists SIGINT as 2, SIGABRT as 6, SIGKILL as 9, SIGSEGV as 11 and SIGTERM as 15.
  • 125, 126 and 127 can come from Docker itself. The docker run reference reserves them for failures around launching the command.

Container exit codes at a glance

  • 0: success. Deployments only allow restartPolicy: Always, so Kubernetes restarts the container anyway; Jobs treat 0 as completion.
  • 1: a general application error; the cause is in the application's logs.
  • 2: Bash uses it for incorrect use of a builtin, and many CLIs for invalid arguments.
  • 125: docker run itself failed, for example on an unknown flag.
  • 126: the command exists but cannot be invoked, such as a directory or a non-executable file.
  • 127: the command was not found.
  • 128: in Kubernetes on containerd, the container failed to start (reason StartError).
  • 130: SIGINT, usually Ctrl+C in an interactive container.
  • 134: SIGABRT, raised when the process calls abort(3), for example after a failed assertion.
  • 137: SIGKILL, from the OOM killer, an expired stop timeout or a forced kill.
  • 139: SIGSEGV, an invalid memory reference.
  • 143: SIGTERM, a shutdown request.
  • 255: usually exit(-1) wrapped into one byte; ssh also returns 255 for its own errors, and containerd's CRI code uses 255 with reason Unknown when it cannot tell how a container ended.

Exit code 137: OOMKilled or a plain SIGKILL?

SIGKILL cannot be caught or ignored, so the process gets no chance to log anything. Three things commonly send it:

  • The kernel OOM killer, when a container exceeds its memory limit or the node runs out of memory.
  • An expired stop timeout. docker stop sends SIGKILL 10 seconds after SIGTERM for Linux containers. Kubernetes waits for terminationGracePeriodSeconds, 30 seconds by default (pod lifecycle). ECS uses stopTimeout, 30 seconds by default and at most 120 on Fargate (ECS API).
  • A forced or cut-short stop. docker kill sends SIGKILL by default. A kubelet hard eviction or kubectl delete pod --grace-period=0 --force skips the pod's grace period, though the kubelet still sends the stop signal first and, in its current code, waits at least two seconds before SIGKILL.

How to confirm an OOM kill

  • Kubernetes: kubectl describe pod POD_NAME shows Reason: OOMKilled and Exit Code: 137 under Last State; the memory limits tutorial shows the same values in kubectl get pod -o yaml under lastState.terminated. For every container at once: kubectl get pod POD_NAME -o jsonpath='{range .status.containerStatuses[*]}{.name}{" "}{.lastState.terminated.exitCode}{" "}{.lastState.terminated.reason}{"\n"}{end}'.
  • Docker: docker inspect --format '{{.State.ExitCode}} {{.State.OOMKilled}}' CONTAINER. The Engine API sets OOMKilled when a process in the container was killed for running out of memory since it last started; docker events --filter event=oom shows kills live.
  • The host: journalctl -k or dmesg. "Memory cgroup out of memory: Killed process" means a cgroup limit was hit; "Out of memory: Killed process" means the whole machine ran short. Both strings come from the kernel's OOM killer.
  • Amazon ECS: aws ecs describe-tasks returns stopCode, stoppedReason and each container's reason and exitCode (AWS guide). Memory kills appear as an OutOfMemoryError. As of October 2026, stopped tasks stay in the ECS console for only one hour. More managed-container coverage is in our Cloud section.

Fixing an OOM kill

  • Measure usage under real load first: kubectl top pod (needs Metrics Server) and docker stats show current consumption, and your monitoring history shows the peaks. Then raise the limit or lower heap, cache or worker settings.
  • Check that the runtime reads the container limit. The Kubernetes cgroup v2 page names OpenJDK 8u372, 11.0.16 and 15 or later, and Node.js 20.3.0 or later; older versions may size the heap from host memory.
  • When the whole node runs short, QoS sets the order: BestEffort containers get an oom_score_adj of 1000 and Guaranteed ones -997, so pods with no or low memory requests are the likeliest victims (kubelet OOM behaviour).

If the reason is Error rather than OOMKilled and the container died about one grace period after the stop began, the process most likely ignored SIGTERM. The PID 1 section below explains why.

Exit code 143: SIGTERM and graceful shutdown

143 means the process ended because of SIGTERM. Docker sends it on docker stop, Kubernetes sends it to PID 1 of each container when a pod is deleted (rollouts, scale-downs, node drains), and ECS issues the equivalent of docker stop when a task stops (StopTask). Here 143 records a requested stop, not a failure.

Some runtimes produce it on purpose: Node.js's default SIGTERM handler exits with 128 plus the signal number (Node.js docs), and the tini README notes that Java apps can exit with 143 after SIGTERM. If alerting treats any non-zero code as failure, handle SIGTERM and exit 0, or run tini with -e 143 to map it to 0.

In Kubernetes, the preStop hook runs first, then TERM goes to PID 1, and SIGKILL follows when terminationGracePeriodSeconds expires; the hook spends part of that same budget, with a one-off 2-second extension if it overruns. A failed liveness probe takes the same path, and since Kubernetes 1.25 the grace period can be set per probe, stable as of 1.28 (probe docs). A "Liveness probe failed" event means a probe, not a person, triggered the stop. See our Platforms coverage for more on running clusters.

Why containers end with 137 instead of 143

PID 1 is the init process of the container's PID namespace, and the kernel delivers a signal to it only if it has installed a handler; SIGKILL and SIGSTOP from the host are the exceptions (pid_namespaces(7)). An application running as PID 1 without a SIGTERM handler ignores the stop request, waits out the grace period and dies with 137. A shell in front of it does the same: the Dockerfile reference warns that the shell form runs under /bin/sh -c, which does not pass signals.

  • Use the exec form, ENTRYPOINT ["app", "--flag"], and end entrypoint scripts with exec app.
  • Add an init: docker run --init runs docker-init, backed by tini, as PID 1 to forward signals and reap zombies. ECS exposes it as initProcessEnabled.
  • Handle SIGTERM: stop accepting work, finish in-flight requests, exit.
  • If the application expects another signal, set STOPSIGNAL in the Dockerfile; the Kubernetes docs note that many container runtimes respect it.

Exit code 139: segmentation fault

139 is SIGSEGV, an invalid memory reference. It is not how a memory limit is enforced, since that is the OOM killer's job and ends in 137: the process tried to access memory it is not allowed to touch. Common sources are bugs in native code (C or C++ programs, native extensions and bindings), a shared library that does not match what the binary was built against, and stack exhaustion from deep recursion. Look for a "segfault at" line in the node's kernel log, which x86 kernels normally print, then reproduce locally from the same image tag with core dumps enabled. A close relative, 135, is SIGBUS (signal 7 on x86 and ARM), a bad memory access.

Exit codes 125 to 128: the command never started

With Docker, 125 means docker run failed before your code ran, 126 that the command cannot be executed and 127 that it was not found. Check ENTRYPOINT, CMD, execute permissions and PATH.

Kubernetes on containerd reports a failed start as reason StartError with exit code 128 and the runtime's error in the message field, values set in containerd's CRI code. You still see 127 when the command is wrapped in sh -c, because the shell reports it. Repeated failures put the pod into CrashLoopBackOff.

Exit codes 1, 2 and 255: read the application logs

These codes come from the program, so the explanation is in its output: kubectl logs POD_NAME --previous shows the crashed instance, and docker logs works on stopped containers. A language-level error such as Java's OutOfMemoryError is not the kernel OOM killer; if it ends the process, the exit code is the program's own (often 1) and the reason is Error, not OOMKilled. More operations guides are in our DevOps section.

Frequently asked questions

What does exit code 137 mean in Kubernetes?

The container's main process was killed with SIGKILL (128 + 9). Reason: OOMKilled means it hit its memory limit; Reason: Error often means it ignored SIGTERM until the grace period ran out.

Is exit code 143 an error?

Usually not. It means the process stopped on SIGTERM, which Docker, Kubernetes and ECS send during normal stops, rollouts and scale-downs.

How do I fix exit code 137 OOMKilled?

Measure peak memory, then raise the limit or cut the application's usage, for example by sizing the heap to the limit. Make sure the language runtime reads cgroup v2 limits.

What is the difference between exit code 137 and 143?

143 means the process ended on SIGTERM, which it can handle; 137 means SIGKILL, which it cannot. A process that ignores SIGTERM turns an expected 143 into 137 when the stop timeout expires.

What does exit code 139 mean in Docker?

The process crashed with a segmentation fault (SIGSEGV, 128 + 11), usually from a bug or library mismatch in native code. Memory limits are enforced with SIGKILL and exit code 137, so a 139 points at the program rather than the limit.