## The short answer: you can't kill a zombie — it's already dead
A zombie (state `Z`, also called a "defunct" process) isn't running. It has already exited. All that remains is an entry in the kernel's process table holding its 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 you throw at it is simply ignored.
The real problem is the **parent process**, which is failing to reap its children.
## Find the zombies and their parents
```bash
ps -eo pid,ppid,stat,cmd | awk '$3 ~ /^Z/'
```
Or for a specific zombie's parent:
```bash
ps -o ppid= -p <zombie_pid>
```
## Step 1: Nudge the parent
Sending `SIGCHLD` tells the parent a child has terminated, which may prompt a well-behaved-but-sleeping parent to reap it:
```bash
kill -s SIGCHLD <parent_pid>
```
This often does nothing, because the usual cause is a parent with a missing or broken `SIGCHLD` handler. Worth a try since it's non-disruptive.
## Step 2: Kill or restart the parent
When the parent dies, its orphaned children are re-parented to PID 1 (`systemd` or `init`), which reaps them immediately.
```bash
kill -TERM <parent_pid> # try graceful first
kill -KILL <parent_pid> # if it doesn't exit
```
If the parent is a managed service, restart it properly instead:
```bash
systemctl restart <service>
```
## Step 3 (advanced): reap manually with gdb
If killing the parent is unacceptable — say it's a long-running database — attach a debugger and call `waitpid` on its behalf:
```bash
gdb -p <parent_pid>
(gdb) call waitpid(-1, 0, 1) # 1 = WNOHANG
(gdb) detach
(gdb) quit
```
This briefly stops the process and pokes at its internals, so treat it as a last resort on anything you care about.
## When to actually worry
A handful of zombies is harmless — they consume a PID slot and a few bytes of kernel memory, nothing more. They become a real problem only when they accumulate and exhaust the PID space:
```bash
cat /proc/sys/kernel/pid_max # typically 32768 or 4194304
ps -eo stat | grep -c '^Z' # current zombie count
```
If a process is leaking zombies steadily, that's a bug in the parent, and restarting it is the fix while you chase down the root cause.
## A common gotcha: containers
Inside Docker/Kubernetes containers, PID 1 is often your application rather than a real init system, and most applications don't reap orphans. Zombies then pile up with no one to collect them. Fix it at the container level:
```bash
docker run --init your-image
```
Or bake in a minimal init like `tini` or `dumb-init` as your entrypoint. In Kubernetes, `shareProcessNamespace: true` also gives you a reaping pause container.
Only if PID 1 itself is wedged and refusing to reap — which is rare and indicates something badly wrong — is a reboot the answer.