Claude on Question 13, Sep 22
How do I kill a zombie process in Linux that won't respond to SIGTERM?Why SIGTERM (and SIGKILL) won't work
A zombie isn't a running process — it's already dead. It's just an entry in the process table holding the exit status, waiting for its parent to call wait()/waitpid() to collect it. Since there's no execution context left, there's nothing to deliver a signal to. kill -9 on a zombie is a no-op.
The real problem is the parent process, which isn't reaping its children.
Find the zombies and their parents
ps -eo pid,ppid,stat,comm | awk '$3 ~ /^Z/'
Or for more detail:
ps aux | awk '$8 ~ /^Z/ { print }'The PPID column is what you care about.
Option 1: Nudge the parent
Send SIGCHLD to the parent to prompt it to reap:
kill -s SIGCHLD <PPID>
This works if the parent has a working SIGCHLD handler but somehow missed the notification. It usually fails if the parent is genuinely buggy — e.g., it's blocked, ignoring SIGCHLD, or never calls wait() at all.
Option 2: Kill or restart the parent
When the parent dies, its zombie children are reparented to PID 1 (init/systemd), which reaps them immediately.
# Graceful first kill <PPID> # Or if it's a managed service systemctl restart <service-name> # Last resort kill -9 <PPID>
Check whether the parent is something you actually want to kill first:
ps -fp <PPID>
Option 3: Do nothing
A handful of zombies is harmless — they consume a PID slot and a few bytes of kernel memory, no CPU or RAM. Only intervene if:
- •They're accumulating continuously (a leak that will exhaust
kernel.pid_max) - •You're near the PID limit:
cat /proc/sys/kernel/pid_maxvs.ps -e | wc -l
Special case: containers
If the PPID is 1 and zombies still aren't being reaped, you're probably in a container where PID 1 is your application rather than a real init. Most apps don't implement child reaping.
Fixes:
docker run --init ... # Docker injects tini
Or bake a minimal init into the image:
ENTRYPOINT ["/usr/bin/dumb-init", "--"] CMD ["your-app"]
In Kubernetes, shareProcessNamespace: true in the pod spec also gives you a reaping pause container.
Preventing it in your own code
If you wrote the parent, either reap explicitly or tell the kernel you don't care:
signal(SIGCHLD, SIG_IGN); // kernel auto-reaps
Or handle it properly:
void reaper(int sig) {
while (waitpid(-1, NULL, WNOHANG) > 0);
}
signal(SIGCHLD, reaper);The while loop matters — multiple children can exit before your handler runs, and signals aren't queued.
Exact recordShowHideThe model id, the run, the verbatim text with line numbers and its full sha256
- Scored
- answered
- Received
- 2026-09-22 09:05:42 UTC
- Run
- 20260922T090022Z-7ff13b
- Served by
- Claude Platform on AWS · HTTP 200 · finish stop
- Size
- 2,596 characters · 1,621 tokens out incl. hidden reasoning · 22.4 s
End of response · 95 lines · 2,596 characters · sha256 b1a16db038f0fe424c6f344316deffca05f06512f2f93732f50af61d6d95878f