warning linux

Linux Exit Code 143 - Terminated (SIGTERM)

Understanding Linux exit code 143 - the process was terminated by SIGTERM, the standard graceful shutdown signal.

What It Means

Exit code 143 (128 + 15) indicates that the process was terminated by SIGTERM (signal 15). SIGTERM is the default signal sent by the kill command and is a polite request for a process to terminate. Unlike SIGKILL, the process can catch SIGTERM and perform cleanup before exiting.

This is the standard way to gracefully shut down a process and is used extensively by Docker, Kubernetes, systemd, and CI/CD systems.

Common Causes

  • kill <pid> was run (sends SIGTERM by default)
  • Docker stopping a container (docker stop)
  • Kubernetes terminating a pod during scaling or deployment
  • Systemd stopping a service (systemctl stop)
  • Process manager (PM2, supervisor) restarting a process
  • CI/CD pipeline cancelling or timing out a job

How to Fix

Handle SIGTERM in bash

#!/bin/bash

shutdown() {
  echo "Received SIGTERM, shutting down gracefully..."
  # Clean up resources
  kill $CHILD_PID 2>/dev/null
  wait $CHILD_PID
  echo "Cleanup complete"
  exit 0
}

trap shutdown SIGTERM

# Start a background process
./worker &
CHILD_PID=$!

# Wait for the background process
wait $CHILD_PID

Handle in Node.js

const http = require('http');
const server = http.createServer(app);

function gracefulShutdown(signal) {
  console.log(`Received ${signal}. Starting graceful shutdown...`);

  server.close(() => {
    console.log('HTTP server closed.');
    // Close database connections, flush logs, etc.
    db.close().then(() => {
      console.log('Database connections closed.');
      process.exit(0);
    });
  });

  // Force exit after 10 seconds
  setTimeout(() => {
    console.error('Forced shutdown after timeout');
    process.exit(1);
  }, 10000);
}

process.on('SIGTERM', () => gracefulShutdown('SIGTERM'));
process.on('SIGINT', () => gracefulShutdown('SIGINT'));

Handle in Python

import signal
import sys

def graceful_shutdown(signum, frame):
    print(f"Received signal {signum}, shutting down...")
    # Close database connections, flush buffers, etc.
    db.close()
    sys.exit(0)

signal.signal(signal.SIGTERM, graceful_shutdown)
signal.signal(signal.SIGINT, graceful_shutdown)

Docker: Ensure SIGTERM reaches your app

# Bad: SIGTERM goes to shell, not your app
CMD node app.js

# Good: exec form ensures SIGTERM reaches Node.js directly
CMD ["node", "app.js"]

# If you need shell features, use exec
CMD exec node app.js

Kubernetes graceful shutdown

# Give your pod enough time to shut down
spec:
  terminationGracePeriodSeconds: 30
  containers:
    - name: app
      lifecycle:
        preStop:
          exec:
            command: ["/bin/sh", "-c", "sleep 5"]  # Allow in-flight requests to complete

Systemd service configuration

[Service]
ExecStop=/bin/kill -SIGTERM $MAINPID
TimeoutStopSec=30  # Wait 30s before sending SIGKILL