Claude on Question 13, Sep 20
How do I kill a zombie process in Linux that won't respond to SIGTERM?Short answer: you can't kill a zombie — it's already dead
A zombie (state Z, also shown as defunct) isn't a running process. It's just an entry in the kernel's process table holding an exit status, waiting for its parent to call wait()/waitpid() and collect it. There's no code executing, so signals — SIGTERM, SIGKILL, anything — are simply discarded.
The fix is always to deal with the parent.
Step 1: Find the zombies and their parents
ps -eo pid,ppid,stat,comm | awk '$3 ~ /^Z/'
Or for a specific zombie's parent:
ps -o ppid= -p <zombie_pid>
Step 2: Nudge the parent to reap
kill -s SIGCHLD <parent_pid>
Well-behaved programs have a SIGCHLD handler that calls waitpid(). This is the polite option and sometimes works if the parent just missed a notification.
Step 3: Kill or restart the parent
If the parent is buggy (ignoring SIGCHLD, blocked, or never calling wait()), terminate it:
kill <parent_pid> # try graceful first kill -9 <parent_pid> # if it won't go
When the parent dies, the zombie is re-parented to PID 1 (init/systemd), which reaps orphans immediately. The zombie disappears.
If it's a managed service, prefer:
systemctl restart <service>
Should you even bother?
A zombie consumes essentially nothing — one process table slot, a few hundred bytes. A handful is cosmetic noise. What matters is the rate: if the count keeps climbing, you'll eventually exhaust the PID space (/proc/sys/kernel/pid_max) and fork() will start failing system-wide. Watch the trend:
watch -n 5 'ps -eo stat | grep -c "^Z"'
The common real-world cause: containers
If you're seeing this in Docker/Kubernetes, the usual culprit is an application running as PID 1 that doesn't implement child reaping. Normal init systems do this automatically; your Node/Python/Java process does not.
docker run --init your-image
Or bake in a minimal init like tini or dumb-init:
ENTRYPOINT ["/usr/bin/tini", "--"] CMD ["your-app"]
If the parent is PID 1
Zombies parented to a healthy systemd should never persist — if they do, that's a genuine kernel or systemd bug. There's no userspace way to clear them; a reboot is the only remedy. This is rare enough that you should double-check the PPID first.
Underlying bug worth fixing
If it's your code, the long-term fix is either a proper SIGCHLD handler that loops until drained:
while (waitpid(-1, NULL, WNOHANG) > 0);
or, if you don't care about exit statuses, explicitly opt out of zombie creation:
signal(SIGCHLD, SIG_IGN);
Exact recordShowHideThe model id, the run, the verbatim text with line numbers and its full sha256
- Scored
- answered
- Received
- 2026-09-20 09:05:32 UTC
- Run
- 20260920T090019Z-bbedf3
- Served by
- Claude Platform on AWS · HTTP 200 · finish stop
- Size
- 2,687 characters · 1,658 tokens out incl. hidden reasoning · 23.2 s
End of response · 83 lines · 2,687 characters · sha256 cdb31dd3c1fc2ec448172d1e058e399205cae5e6bf7beec28512f2a1ff00d695