Error reference

Exit Code 143: What SIGTERM Means in Docker and Kubernetes

Updated July 27, 2026

In short
Exit code 143 means the process ended after receiving SIGTERM (128 + 15): a polite shutdown request, not a crash. In Kubernetes it is almost always normal lifecycle: a rolling deploy, scale-down, node drain, or failed liveness probe triggered the termination. Find who sent it with kubectl describe pod <pod-name> and read the Events. If your app needs cleanup time, handle SIGTERM and tune terminationGracePeriodSeconds (default 30s): processes that ignore SIGTERM get escalated to SIGKILL and exit 137 instead.
start here
kubectl get pod <pod-name> -o jsonpath='{.status.containerStatuses[0].lastState.terminated}'
Diagnosis

Causes at a glance

CauseHow to recognize itFix
Rolling deploymentEvents show Killing while a new ReplicaSet scales upExpected behavior: make sure the app shuts down cleanly on SIGTERM
Scale-down (HPA or manual)Replica count dropped; HPA events show SuccessfulRescaleExpected: verify graceful shutdown and set a PodDisruptionBudget
Node drain or evictionNode was cordoned/drained; pod rescheduled to another nodeNormal during upgrades and spot reclaims; add a PodDisruptionBudget
Failing liveness probeEvents show "Liveness probe failed" just before KillingFix the probe endpoint or timing so kubelet stops restarting the pod
docker stop / compose downManual or scripted stop outside KubernetesExpected: raise the grace period with docker stop -t if cleanup is slow

What exit code 143 actually means

Linux reports a signal death as 128 + the signal number. SIGTERM is signal 15, so 128 + 15 = 143. SIGTERM is the catchable "please shut down" signal: the process is allowed to finish requests, flush buffers, and exit on its own terms.

That also means 143 is informative: if your app caught SIGTERM and exited cleanly, it would typically return 0. Seeing 143 usually means the default signal handler killed the process mid-work: nothing broke, but nothing was cleaned up either.

echo $((128 + 15))  # 143 = SIGTERM (graceful stop requested)
echo $((128 + 9))   # 137 = SIGKILL (force-killed)
Step 1

Step 1: find out who sent the SIGTERM

The signal itself carries no sender information, but Kubernetes leaves a paper trail. Correlate the termination timestamp with events: a deploy shows ScalingReplicaSet, a probe failure shows "Liveness probe failed", a drain shows the node being cordoned.

kubectl describe pod <pod-name> | grep -A 10 Events
kubectl get events --sort-by=.lastTimestamp -n <namespace>
# look for: Killing, ScalingReplicaSet, Liveness probe failed, NodeNotReady
Step 2

Step 2: handle SIGTERM in your application

Register a SIGTERM handler that stops accepting new work, finishes in-flight requests, closes connections, and exits. Without one, requests in flight are dropped the moment the process dies, which is why 143s during deploys correlate with 5xx spikes.

Watch out for the PID 1 trap: with a shell-form ENTRYPOINT (ENTRYPOINT npm start), the shell is PID 1 and does not forward SIGTERM to your app, so the container ignores the signal until SIGKILL. Use the exec form (ENTRYPOINT ["node", "server.js"]), exec inside wrapper scripts, or an init like tini (docker run --init).

// Node.js
process.on('SIGTERM', () => {
  server.close(() => process.exit(0));
});

# Python
import signal, sys
signal.signal(signal.SIGTERM, lambda *_: sys.exit(0))
Step 3

Step 3: give shutdown enough time (grace period and preStop)

Kubernetes runs the preStop hook first, then sends SIGTERM, then waits out terminationGracePeriodSeconds (default 30s, counted from termination start, including preStop) before SIGKILL. A short preStop sleep gives load balancers time to remove the pod from endpoints before the app stops accepting traffic.

spec:
  terminationGracePeriodSeconds: 60
  containers:
    - name: app
      lifecycle:
        preStop:
          exec:
            command: ["sleep", "10"]  # let endpoints/LBs drain first

Exit code 143 vs 137

They are the two halves of the same shutdown protocol: 143 means the process died on SIGTERM (the polite request), 137 means it was force-killed with SIGKILL: either because it ignored SIGTERM past the grace period, or because the OOM killer fired. If your deploys produce 137s instead of 143s, your shutdown handler is too slow or not receiving the signal at all.

Beyond the one-off fix

Every 143 is the fingerprint of an intentional action: something initiated that shutdown. When AI agents run deploys and scale services, "who terminated these pods" needs a better answer than a service-account name in an audit log. Nexus records each agent-initiated rollout and scaling action with the full context of why the agent did it, so a wave of SIGTERMs traces back to the exact decision that caused it.

Explore Swfte Nexus

Common questions

Is exit code 143 an error?
Usually not. It means the container was asked to stop with SIGTERM and did, which is exactly what happens in every rolling deploy, scale-down, and node drain. It only indicates a problem when it appears outside those lifecycle events, or when your app needed to clean up and did not.
Why do my pods exit with code 143 during every deploy?
Because a rolling update terminates old pods with SIGTERM as new ones become ready. That is by design. The thing to verify is that your app handles SIGTERM gracefully so in-flight requests finish instead of being dropped.
Why does my container ignore SIGTERM and get SIGKILLed instead?
Most often because a shell is PID 1 and swallows the signal: a shell-form ENTRYPOINT or a wrapper script that does not use exec. Switch to the exec form of ENTRYPOINT, prefix the final command in scripts with exec, or run with an init process like tini.
How long does Kubernetes wait after sending SIGTERM?
terminationGracePeriodSeconds, which defaults to 30 seconds and includes any preStop hook time. If the process is still alive when it expires, the kubelet sends SIGKILL and the container exits 137.
What is the difference between exit code 143 and exit code 137?
143 is SIGTERM (128+15): a graceful stop the process could react to. 137 is SIGKILL (128+9): an unblockable force kill, caused by the OOM killer or by a grace period expiring. 143 is normally fine; 137 always deserves a look.