MODELDRIFT.WATCH

Question 13 · Sep 17 · Day 8

Claude on Question 13, Sep 17

How do I kill a zombie process in Linux that won't respond to SIGTERM?

The key insight: you can't kill a zombie

A zombie (state Z, shown as <defunct>) is already dead. It's not a running process — it's just an entry in the process table holding an exit status, waiting for its parent to call wait()/waitpid() and collect it. Since there's no code executing, signals have nowhere to go. SIGTERM, SIGKILL, anything — all ignored.

The problem isn't the zombie. It's the parent process that isn't reaping its children.

Find the parent

ps -eo pid,ppid,stat,cmd | awk '$3 ~ /^Z/ { print }'

Or with ps aux, zombies show up with Z in the STAT column and <defunct> in the command.

Option 1: Nudge the parent

kill -s SIGCHLD <parent_pid>

This tells the parent "hey, a child died, go reap it." Works if the parent has a working SIGCHLD handler but somehow missed the notification. Often it doesn't help, because the reason you have zombies is that the parent has no handler or is stuck.

Option 2: Kill the parent

kill <parent_pid>          # try graceful first
kill -9 <parent_pid>       # if that fails

When the parent dies, the zombie is re-parented to init/systemd (PID 1), which reaps orphans automatically. The zombie disappears within moments.

Obvious caveat: make sure killing the parent is acceptable. If the parent is sshd, your web server, or a database supervisor, you're trading a harmless zombie for real downtime. Restarting the service properly (systemctl restart foo) accomplishes the same thing more safely.

Should you even care?

A handful of zombies consumes one PID slot each and essentially zero memory or CPU. It's cosmetically annoying, not harmful.

It matters when they accumulate — thousands of zombies can exhaust the PID space and you'll start seeing fork: Resource temporarily unavailable. Check your limit:

cat /proc/sys/kernel/pid_max
ps -eo stat | grep -c Z

Steady accumulation means a genuine bug in the parent: it's forking without ever calling wait(). The real fix is in that program — install a SIGCHLD handler, or set signal(SIGCHLD, SIG_IGN) so the kernel auto-reaps. In containers this is common with an application as PID 1 that doesn't reap; the fix is a proper init like tini or docker run --init.

One common mix-up

If signals genuinely aren't working and the state is D rather than Z, that's uninterruptible sleep, not a zombie. That process is alive but blocked in a kernel call — usually hung I/O, a dead NFS mount, or a failing disk. It also can't be killed, but for entirely different reasons, and the fix is addressing the underlying I/O problem (remount the NFS share, check dmesg for disk errors). Sometimes only a reboot clears it.

sha256 f860a93084af… · 33 tokens in · 1,620 out · 22.7 s · via Claude Platform on AWS · stopped on its own

Sep 17, the whole dayQuestion 13, every day

Exact recordShowHideThe model id, the run, the verbatim text with line numbers and its full sha256
Model
anthropic/claude-opus-5
pinned anthropic/claude-opus-5-20260723; alias resolved to anthropic/claude-opus-5-20260723 at 2026-09-17 09:00:21 UTC (matches the pin)
Date
2026-09-17 · run 20260917T090022Z-136fc3 · scorer v1
Scored
answered
sha256
f860a93084af979c16add7e5a4fa1ebdae13aae11b6dfaaaaba7c30eb13f99e5
Permalink
https://modeldrift.watch/r/2026-09-17/R1/anthropic/claude-opus-5/
Scored
answered
Received
2026-09-17 09:06:16 UTC
Run
20260917T090022Z-136fc3
Served by
Claude Platform on AWS · HTTP 200 · finish stop
Size
2,737 characters · 1,620 tokens out incl. hidden reasoning · 22.7 s
## The key insight: you can't kill a zombie
A zombie (state `Z`, shown as `<defunct>`) is already dead. It's not a running process — it's just an entry in the process table holding an exit status, waiting for its parent to call `wait()`/`waitpid()` and collect it. Since there's no code executing, signals have nowhere to go. `SIGTERM`, `SIGKILL`, anything — all ignored.
The problem isn't the zombie. It's the **parent process** that isn't reaping its children.
## Find the parent
```bash
ps -eo pid,ppid,stat,cmd | awk '$3 ~ /^Z/ { print }'
```
Or with `ps aux`, zombies show up with `Z` in the STAT column and `<defunct>` in the command.
## Option 1: Nudge the parent
```bash
kill -s SIGCHLD <parent_pid>
```
This tells the parent "hey, a child died, go reap it." Works if the parent has a working `SIGCHLD` handler but somehow missed the notification. Often it doesn't help, because the reason you have zombies is that the parent has no handler or is stuck.
## Option 2: Kill the parent
```bash
kill <parent_pid> # try graceful first
kill -9 <parent_pid> # if that fails
```
When the parent dies, the zombie is re-parented to `init`/`systemd` (PID 1), which reaps orphans automatically. The zombie disappears within moments.
Obvious caveat: make sure killing the parent is acceptable. If the parent is `sshd`, your web server, or a database supervisor, you're trading a harmless zombie for real downtime. Restarting the service properly (`systemctl restart foo`) accomplishes the same thing more safely.
## Should you even care?
A handful of zombies consumes one PID slot each and essentially zero memory or CPU. It's cosmetically annoying, not harmful.
It matters when they accumulate — thousands of zombies can exhaust the PID space and you'll start seeing `fork: Resource temporarily unavailable`. Check your limit:
```bash
cat /proc/sys/kernel/pid_max
ps -eo stat | grep -c Z
```
Steady accumulation means a genuine bug in the parent: it's forking without ever calling `wait()`. The real fix is in that program — install a `SIGCHLD` handler, or set `signal(SIGCHLD, SIG_IGN)` so the kernel auto-reaps. In containers this is common with an application as PID 1 that doesn't reap; the fix is a proper init like `tini` or `docker run --init`.
## One common mix-up
If signals genuinely aren't working and the state is `D` rather than `Z`, that's **uninterruptible sleep**, not a zombie. That process is alive but blocked in a kernel call — usually hung I/O, a dead NFS mount, or a failing disk. It also can't be killed, but for entirely different reasons, and the fix is addressing the underlying I/O problem (remount the NFS share, check `dmesg` for disk errors). Sometimes only a reboot clears it.

End of response · 49 lines · 2,737 characters · sha256 f860a93084af979c16add7e5a4fa1ebdae13aae11b6dfaaaaba7c30eb13f99e5