How to fix Container was killed with SIGKILL in Docker

DockerINTERMEDIATEHIGHUpdated Dec 6, 2025ยท 252 views

This error occurs when a Docker container receives the SIGKILL signal (signal 9), causing immediate termination without graceful shutdown. Common causes include OOM killer, docker stop timeouts, manual kill commands, or orchestration systems forcefully terminating containers.

Quick fix

Fixes Container was killed with SIGKILL

# Check exit code (137 = SIGKILL)
docker inspect --format='{{.State.ExitCode}}' <container_name>

# Check if OOM killed
docker inspect --format='{{.State.OOMKilled}}' <container_name>

# View container state details
docker inspect --format='{{json .State}}' <container_name> | jq

# Check system logs for OOM events
dmesg | grep -i "killed process"
dmesg | grep -i "out of memory"
  1. Identify the cause of SIGKILL
  2. Ensure your application handles SIGTERM properly
  3. Use exec form for CMD and ENTRYPOINT
  4. Increase the stop grace period
docker โ€” error
# Check exit code (137 = SIGKILL)
docker inspect --format='{{.State.ExitCode}}' <container_name>
# Check if OOM killed
docker inspect --format='{{.State.OOMKilled}}' <container_name>
# View container state details
docker inspect --format='{{json .State}}' <container_name> | jq
# Check system logs for OOM events
dmesg | grep -i "killed process"
dmesg | grep -i "out of memory"
Container was killed with SIGKILL

What this error means

The "Container was killed with SIGKILL" message indicates that your Docker container received the SIGKILL signal (signal number 9), which causes immediate and unconditional termination. Unlike SIGTERM, SIGKILL cannot be caught, blocked, or ignored by the process - the kernel forcefully terminates it. When a container exits due to SIGKILL, it will have exit code 137 (calculated as 128 + 9, where 9 is the signal number). This exit code is the key indicator that distinguishes a SIGKILL termination from other types of container failures. SIGKILL is typically a last resort signal used when: 1. A process doesn't respond to SIGTERM within a grace period 2. The system's OOM (Out of Memory) killer needs to free memory urgently 3. An administrator or orchestration system needs to force-stop a container 4. Docker's stop command times out waiting for graceful shutdown The abrupt nature of SIGKILL means the application has no opportunity to perform cleanup operations like closing database connections, flushing buffers, or saving state.

Typical symptoms

  • Container exits with exit code 137
  • Logs show 'Killed' message without application-level error
  • docker inspect shows the container was killed by signal 9
  • Application data may be corrupted or incomplete due to abrupt termination
  • Container restarts repeatedly if restart policy is set
  • No graceful shutdown logs from application (shutdown hooks not executed)
  • dmesg may show OOM killer messages if memory-related

Common causes

  1. docker stop command timed out waiting for SIGTERM response (default 10 seconds)
  2. OOM killer terminated the container due to memory exhaustion
  3. Manual docker kill command was issued
  4. Orchestration system (Kubernetes, Swarm) forcefully terminated the container
  5. Application doesn't handle SIGTERM signal and ignores shutdown requests
  6. Process running as PID 1 with shell form CMD/ENTRYPOINT doesn't forward signals
  7. System shutdown or Docker daemon restart forced container termination
  8. Host system under memory pressure killing processes

How to fix "Container was killed with SIGKILL"

1Identify the cause of SIGKILL

First, determine why your container received SIGKILL:

bash
# Check exit code (137 = SIGKILL)
docker inspect --format='{{.State.ExitCode}}' <container_name>

# Check if OOM killed
docker inspect --format='{{.State.OOMKilled}}' <container_name>

# View container state details
docker inspect --format='{{json .State}}' <container_name> | jq

# Check system logs for OOM events
dmesg | grep -i "killed process"
dmesg | grep -i "out of memory"

If OOMKilled is true, see the memory-related solutions. If false, the container was killed for another reason (timeout, manual kill, etc.).

2Ensure your application handles SIGTERM properly

Docker sends SIGTERM first, then SIGKILL after timeout. Make sure your application handles SIGTERM:

Node.js example:

javascript
process.on('SIGTERM', () => {
  console.log('Received SIGTERM, shutting down gracefully...');
  server.close(() => {
    console.log('Server closed');
    process.exit(0);
  });

  // Force exit after 10 seconds if graceful shutdown fails
  setTimeout(() => {
    console.error('Graceful shutdown timed out, forcing exit');
    process.exit(1);
  }, 10000);
});

Python example:

python
import signal
import sys

def handle_sigterm(signum, frame):
    print("Received SIGTERM, shutting down...")
    # Cleanup code here
    sys.exit(0)

signal.signal(signal.SIGTERM, handle_sigterm)

Go example:

go
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGTERM)

go func() {
    <-sigChan
    log.Println("Received SIGTERM, shutting down...")
    // Cleanup and shutdown
    os.Exit(0)
}()
3Use exec form for CMD and ENTRYPOINT

Shell form prevents your application from receiving signals directly:

Wrong (shell form):

dockerfile
# Runs as: /bin/sh -c "node server.js"
# PID 1 is sh, not node - signals don't reach your app
CMD node server.js
ENTRYPOINT python app.py

Correct (exec form):

dockerfile
# Runs directly, your app is PID 1
CMD ["node", "server.js"]
ENTRYPOINT ["python", "app.py"]

If you must use a shell script as entrypoint, use exec:

bash
#!/bin/bash
# entrypoint.sh

# Setup code here...

# Use exec to replace shell with your app
exec node server.js

This ensures your application becomes PID 1 and receives signals directly.

4Increase the stop grace period

If your application needs more time to shut down gracefully, increase the timeout:

Docker run:

bash
# Give 30 seconds instead of default 10
docker stop --time=30 <container_name>

# Or wait indefinitely for graceful shutdown
docker stop --time=-1 <container_name>

Docker Compose:

yaml
services:
  myapp:
    image: myimage:latest
    stop_grace_period: 30s

Dockerfile (set default):

dockerfile
# Set default stop signal and timeout
STOPSIGNAL SIGTERM
# Note: STOPSIGNAL only changes the signal, not the timeout

Kubernetes:

yaml
spec:
  terminationGracePeriodSeconds: 30
5Use an init system for proper signal handling

If your application can't be modified to handle signals, use a lightweight init system:

Using tini (recommended):

dockerfile
# Install tini
RUN apt-get update && apt-get install -y tini

# Use tini as entrypoint
ENTRYPOINT ["/usr/bin/tini", "--"]
CMD ["node", "server.js"]

Or with Alpine:

dockerfile
FROM alpine:latest
RUN apk add --no-cache tini
ENTRYPOINT ["/sbin/tini", "--"]
CMD ["./myapp"]

Using dumb-init:

dockerfile
RUN apt-get update && apt-get install -y dumb-init
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
CMD ["python", "app.py"]

Using Docker's built-in init:

bash
docker run --init myimage

Or in Compose:

yaml
services:
  myapp:
    image: myimage
    init: true

These init systems properly forward signals to child processes and reap zombie processes.

6Address OOM-related SIGKILL

If the container is being killed by the OOM killer:

Increase memory limits:

bash
docker run --memory=2g --memory-swap=2g myimage

Monitor memory usage:

bash
docker stats <container_name>

Configure runtime memory limits:

For Node.js:

bash
docker run --memory=1g -e NODE_OPTIONS="--max-old-space-size=768" myapp

For Java:

bash
docker run --memory=2g -e JAVA_OPTS="-XX:MaxRAMPercentage=75.0" java-app

Check for memory leaks in your application if memory grows unbounded over time.

See the related "Docker OOM Killed" article for comprehensive memory troubleshooting.

7Monitor and prevent unexpected SIGKILL

Set up monitoring to detect and prevent SIGKILL issues:

Monitor Docker events:

bash
# Watch for container kill events in real-time
docker events --filter 'event=kill'
docker events --filter 'event=oom'

Check container exit reasons:

bash
# List recently exited containers with exit codes
docker ps -a --filter "status=exited" --format "{{.Names}}: {{.Status}}"

Log when signals are received:
Add logging to your signal handlers so you can see in container logs whether SIGTERM was received and how long shutdown took.

Set up alerts:
In production, configure alerts for:
- Containers exiting with code 137
- OOM events
- Containers that restart frequently

Advanced notes

Understanding exit code 137: Exit code 137 specifically indicates SIGKILL (128 + signal number). Common signal-related exit codes:
- 137 = SIGKILL (128 + 9) - Forced termination
- 143 = SIGTERM (128 + 15) - Graceful termination request
- 130 = SIGINT (128 + 2) - Interrupt (Ctrl+C)
- 139 = SIGSEGV (128 + 11) - Segmentation fault

PID 1 special behavior: In Linux, PID 1 has special signal handling. It only receives signals for which it has explicitly installed handlers. This is why shell form CMD doesn't forward SIGTERM - the shell (PID 1) has no handler, and child processes don't receive it.

Docker stop sequence:
1. Docker sends SIGTERM (or configured STOPSIGNAL) to PID 1
2. Docker waits for stop timeout (default 10s)
3. If container still running, Docker sends SIGKILL

Kubernetes termination sequence:
1. Pod marked as "Terminating"
2. PreStop hook executed (if defined)
3. SIGTERM sent to containers
4. terminationGracePeriodSeconds countdown begins
5. SIGKILL sent if pod still running

Debugging signal issues:

bash
# See what process is PID 1 in container
docker exec <container> ps aux

# Check if your app is actually PID 1
docker exec <container> cat /proc/1/cmdline

Custom stop signals: Some applications expect different signals. Configure in Dockerfile:

dockerfile
STOPSIGNAL SIGQUIT  # For nginx graceful shutdown

Or at runtime:

bash
docker run --stop-signal=SIGQUIT nginx

Docker Compose v2 behavior: Docker Compose v2 uses a different stop behavior than v1. Ensure your stop_grace_period is set explicitly if migrating.

Frequently asked questions

What does "Container was killed with SIGKILL" mean?
The "Container was killed with SIGKILL" message indicates that your Docker container received the SIGKILL signal (signal number 9), which causes immediate and unconditional termination. Unlike SIGTERM, SIGKILL cannot be caught, blocked, or ignored by the process - the kernel forcefully terminates it. When a container exits due to SIGKILL, it will have exit code 137 (calculated as 128 + 9, where 9 is the signal number).
How do I fix "Container was killed with SIGKILL"?
This error occurs when a Docker container receives the SIGKILL signal (signal 9), causing immediate termination without graceful shutdown. Common causes include OOM killer, docker stop timeouts, manual kill commands, or orchestration systems forcefully terminating containers.
What causes "Container was killed with SIGKILL"?
docker stop command timed out waiting for SIGTERM response (default 10 seconds) OOM killer terminated the container due to memory exhaustion Manual docker kill command was issued
Is the "Container was killed with SIGKILL" error serious?
Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.

Official resources & further reading