MODELDRIFT.WATCH

Question 13 · Oct 2 · Day 23

Claude on Question 13, Oct 2

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

The short answer: you can't kill a zombie, because it's already dead. Signals have no effect on it.

What a zombie actually is

A zombie (state Z, shown as <defunct>) is a process that has already exited. The kernel keeps a minimal entry in the process table holding its exit status, waiting for the parent to collect it with wait()/waitpid(). There's no memory, no code, no threads — nothing to signal. kill -9 is a no-op.

So the problem isn't the zombie, it's the parent that isn't reaping it.

Find the zombie and its parent

ps -eo pid,ppid,stat,comm | awk '$3 ~ /^Z/'

Or with more context:

ps aux | grep -w 'Z' | grep -v grep

Get the parent PID directly:

ps -o ppid= -p <zombie_pid>

Step 1: Nudge the parent

Send the parent a SIGCHLD to prompt it to reap:

kill -s SIGCHLD <parent_pid>

Well-behaved programs will call wait() and the zombie disappears. Buggy ones ignore it.

Step 2: Kill the parent

If the parent won't reap, kill it. When the parent dies, its children are re-parented to init/systemd (PID 1), which reaps zombies automatically.

kill <parent_pid>      # try SIGTERM first
kill -9 <parent_pid>   # if needed

Check what the parent is first — if it's a long-running service with other healthy children, restarting the service cleanly is better:

systemctl restart <service>

One caveat on modern systems: if something in the ancestry called prctl(PR_SET_CHILD_SUBREAPER) (user-level systemd --user, container runtimes, some supervisors), orphans get re-parented to that process instead of PID 1. If that subreaper is also broken, you may need to go up another level.

Step 3: Reboot

Only if the parent is PID 1 itself or something you can't restart. Rarely necessary.


Is it worth bothering?

A handful of zombies costs you one PID table slot each and nothing else. They're ugly but harmless. The real risk is a parent leaking them continuously until you hit kernel.pid_max and can't fork anything. Check the trend:

watch -n 5 "ps -eo stat | grep -c '^Z'"

If it's climbing, that's a bug in the parent worth reporting or patching.

Two things often mistaken for zombies

  • •State D (uninterruptible sleep) — a process genuinely stuck in a kernel call, usually blocked I/O on NFS, a failing disk, or a wedged FUSE mount. These do ignore SIGKILL, which is why people confuse them with zombies. Fix the underlying I/O (remount, umount -f, check dmesg); the process unblocks or you reboot.
  • •Containers — if your app runs directly as PID 1 in a container, it probably doesn't reap, so zombies pile up. Use docker run --init, or bake in tini/dumb-init as the entrypoint.

sha256 5ead36eadf96… · 33 tokens in · 1,878 out · 25.0 s · via Claude Platform on AWS · stopped on its own

Oct 2, 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-10-02 09:00:07 UTC (matches the pin)
Date
2026-10-02 · run 20261002T090008Z-e178a0 · scorer v1
Scored
answered
sha256
5ead36eadf9654ab5331cf9f0bfb01381cc25365130bfe10ddebc59348da4294
Permalink
https://modeldrift.watch/r/2026-10-02/R1/anthropic/claude-opus-5/
Scored
answered
Received
2026-10-02 09:05:38 UTC
Run
20261002T090008Z-e178a0
Served by
Claude Platform on AWS · HTTP 200 · finish stop
Size
2,766 characters · 1,878 tokens out incl. hidden reasoning · 25.0 s
The short answer: you can't kill a zombie, because it's already dead. Signals have no effect on it.
**What a zombie actually is**
A zombie (state `Z`, shown as `<defunct>`) is a process that has already exited. The kernel keeps a minimal entry in the process table holding its exit status, waiting for the parent to collect it with `wait()`/`waitpid()`. There's no memory, no code, no threads — nothing to signal. `kill -9` is a no-op.
So the problem isn't the zombie, it's the **parent that isn't reaping it**.
**Find the zombie and its parent**
```bash
ps -eo pid,ppid,stat,comm | awk '$3 ~ /^Z/'
```
Or with more context:
```bash
ps aux | grep -w 'Z' | grep -v grep
```
Get the parent PID directly:
```bash
ps -o ppid= -p <zombie_pid>
```
**Step 1: Nudge the parent**
Send the parent a `SIGCHLD` to prompt it to reap:
```bash
kill -s SIGCHLD <parent_pid>
```
Well-behaved programs will call `wait()` and the zombie disappears. Buggy ones ignore it.
**Step 2: Kill the parent**
If the parent won't reap, kill it. When the parent dies, its children are re-parented to `init`/`systemd` (PID 1), which reaps zombies automatically.
```bash
kill <parent_pid> # try SIGTERM first
kill -9 <parent_pid> # if needed
```
Check what the parent is first — if it's a long-running service with other healthy children, restarting the service cleanly is better:
```bash
systemctl restart <service>
```
One caveat on modern systems: if something in the ancestry called `prctl(PR_SET_CHILD_SUBREAPER)` (user-level `systemd --user`, container runtimes, some supervisors), orphans get re-parented to *that* process instead of PID 1. If that subreaper is also broken, you may need to go up another level.
**Step 3: Reboot**
Only if the parent is PID 1 itself or something you can't restart. Rarely necessary.
---
**Is it worth bothering?**
A handful of zombies costs you one PID table slot each and nothing else. They're ugly but harmless. The real risk is a parent leaking them continuously until you hit `kernel.pid_max` and can't fork anything. Check the trend:
```bash
watch -n 5 "ps -eo stat | grep -c '^Z'"
```
If it's climbing, that's a bug in the parent worth reporting or patching.
**Two things often mistaken for zombies**
- **State `D`** (uninterruptible sleep) — a process genuinely stuck in a kernel call, usually blocked I/O on NFS, a failing disk, or a wedged FUSE mount. These *do* ignore `SIGKILL`, which is why people confuse them with zombies. Fix the underlying I/O (remount, `umount -f`, check `dmesg`); the process unblocks or you reboot.
- **Containers** — if your app runs directly as PID 1 in a container, it probably doesn't reap, so zombies pile up. Use `docker run --init`, or bake in `tini`/`dumb-init` as the entrypoint.

End of response · 73 lines · 2,766 characters · sha256 5ead36eadf9654ab5331cf9f0bfb01381cc25365130bfe10ddebc59348da4294