What Is a Defunct Zombie Process in Linux?

What Is a Defunct Zombie Process in Linux?

A defunct process in Linux output can leave you wondering which process is responsible for it. A zombie process has finished running, but its parent has not collected its exit status.

I’ll show you how to identify the zombie’s parent and what to check before taking action.

TL;DR

A zombie process has exited, but its parent has not yet collected its exit status with a wait-family call.

  • Find processes in state Z and note each zombie’s PID and PPID.
  • You cannot remove a zombie by signaling its PID because it has already stopped executing.
  • Ask the parent to reap its child by fixing or restarting that parent only when it is safe.

What Is a Defunct Zombie Process?

Defunct and zombie are two names for the same process state. I define it before describing cleanup because the child and its parent have different roles. The retained kernel record holds the PID, termination status, and resource-usage information.

SIGCHLD can notify the parent when a child changes state, including termination. The notification prompts a check but does not collect status, and one signal is not a count of finished children.

An orphan remains alive after its parent exits, while a zombie has terminated. Linux reparents orphaned children to a subreaper, a process configured to adopt orphaned descendants, or to the init process, which can collect their status.

How to Find and Handle a Zombie Process

I use read-only ps queries first because observation gives a baseline without changing process state.

Step 1: List processes in state Z

Run ps with a state column and filter for Z, the zombie state. The command below prints the header and matching process rows:

ps -eo pid,ppid,state,comm --sort=state | awk 'NR == 1 || $3 == "Z"'

The captured output below shows the header and each matching process:

PID    PPID S COMMAND
 762530    3684 Z python
3608443    3684 Z git
3608505    3684 Z git
3609659    3684 Z git
3609740    3684 Z git
Terminal output listing zombie processes with PID, PPID, state, and command

The state column marks zombies as Z, while PPID names their parent. D describes uninterruptible sleep and T a stopped task, each requiring its own diagnosis. PIDs and command names differ between machines.

Step 2: Inspect the parent process

Use the PPID to identify the process associated with those child exits. Replace 3684 with the PPID shown on your system:

ps -p 3684 -o pid,ppid,state,comm,args

The captured inspection produced:

    PID    PPID S COMMAND         COMMAND
   3684    3575 S python          python server.py
Terminal output identifying a process parent by PID and PPID

The captured list has five Z rows, each with PPID 3684. The second command identifies that parent as python server.py. That result reflects this server at capture time, not expected output on another machine.

This command asks ps to display that parent’s identifiers, state, executable name, and arguments. The PID in the example came from the captured process list. The output identifies the command, not why its children ended.

Use comm instead of args when the executable name is enough, since full command lines can contain private values.

The immediate PPID identifies the child’s parent, while a shell or supervisor can separate it from the service manager that owns restart policy. Before a restart, trace the tree to the service boundary and check the manager’s policy alongside the parent’s health.

You can also inspect a process tree with the site guide to the ps command in Linux. A tree gives more context when several processes are related.

Step 3: Let the parent collect the child status

Use blocking wait() when the parent can pause or WNOHANG with waitpid() when its event loop must continue. waitpid() normally reports terminated children, but WUNTRACED or WCONTINUED also reports stopped or resumed children, which the program must distinguish before treating a child as finished.

Step 4: Escalate only when the parent is safe to stop

Restart a stuck parent through its owning supervisor only when the impact on other children and work is acceptable. Never signal the zombie PID, PID 1, or an unrelated parent as a cleanup shortcut. For signal syntax on live processes, see the site guide to the Linux kill command.

When a service leaves children behind, preserve its logs and compare child exit times with application events. The timestamps can distinguish an expected shutdown from repeated failures during normal work.

Zombie Process Edge Cases and Prevention

I chose a case table because the same process state calls for different responses depending on its parent and the surrounding workload.

CaseWhat it meansNext check
Z in the state columnChild has exited and its status is still available to the parent.Record PID and PPID, then inspect the direct parent.
Parent is runningThe parent still controls whether and when it collects child status.Review the program or service logs and its child-management behavior.
Parent has exitedA subreaper or init process may inherit responsibility for the child.Check the current process tree again because the relationship can change.
A short-lived zombieThe parent may be handling child completion normally.Compare a later read-only process listing before interrupting work.
Count keeps risingThe creator or supervisor may fail to handle repeated child exits.Group entries by PPID and investigate that application’s lifecycle.
Service owns the parentRestarting it may interrupt unrelated child work or requests.Use the service’s approved maintenance procedure and confirm impact.
Parent PID changesReparenting or process exit may have changed the hierarchy.Refresh the listing and use the current PPID instead of an old value.
Failure appears after a restartThe service may create children during startup or recovery.Compare service logs around startup and inspect the configured supervisor.
Zombie belongs to a containerThe container may have a separate process tree and init process.Inspect from the container’s namespace and compare with the host view.
Application needs each exit codeAutomatic discard of child status may break application logic.Choose wait behavior that preserves the status the program consumes.
Only one listing shows ZThe captured state may change before the next check.Take another read-only snapshot before deciding on a service action.

Compare repeated snapshots with the same ps command to see whether an entry persists.

A PID can be reused after reaping, so refresh the listing and confirm the command and PPID before acting. Repeat the check after delays or service restarts because PIDs identify current processes.

Some process listings append <defunct> to the command label, while the PID remains in its own numeric column.

pid_max controls PID allocation and threads-max caps system-wide tasks. Services and cgroups can set narrower limits, and cgroup v2 exposes per-group usage through its pids controller. There is no universal zombie count that signals instability, so compare the trend with the applicable limit and service logs.

A zombie stays associated with its cgroup until reaped, while cgroup.procs omits it. This is why ps and cgroup.procs can show different process lists.

To locate recurring exits, compare parent-application logs with service-manager events and inspect a container’s process tree and init setup in that namespace before choosing a code or supervision change.

POSIX limits calls inside signal handlers, so use an async-signal-safe flag or wake-up and let normal program flow process events and logs.

Explicit SIG_IGN or SA_NOCLDWAIT differs from Linux’s default SIGCHLD disposition and discards terminated-child statuses, avoiding zombies at the cost of exit codes the application may need.

A process can have different PIDs in nested namespaces, and procfs shows the view for its mount. A container’s PID 1 is scoped to its namespace, where it adopts orphaned children and needs appropriate child handling or an init.

Group current entries by PPID and align them with parent logs or application events to find the component whose code or supervisor needs attention.

Worker-creation failures can delay requests or leave jobs unprocessed, so compare service logs with applicable task limits and application errors before linking them to zombie processes.

A zombie has no live code or listening socket, so review attack surface through the parent’s listeners, privileges, patch state, and logs rather than the count itself.

Test child handling under the production supervisor during concurrent exits and graceful shutdown, then check logs and process listings for sustained Z growth before calling the fix reliable.

Conclusion: Let the Parent Reap the Child

Read the cited wait and namespace manuals before changing a parent application’s child-handling policy.

For related diagnostics, read the Linux guides to ps and top. For system-call details, see the Linux wait(2) manual, the PID namespaces manual, the Linux kernel cgroup v2 documentation, and the htop manual.

FAQ

These answers cover the common checks and cleanup questions for a defunct process.

Can you kill a zombie process?

No. It has already exited, so a signal to its PID cannot stop it again. Its parent or an adopting reaper must collect its exit status.

Do zombie processes use resources?

A zombie does not execute or consume ongoing CPU time, but it retains a PID and a small process-table entry until it is reaped. Accumulation can contribute to process-creation limits.

How do I find zombie processes in Linux?

Use ps with a state column and identify rows whose state is Z. Include the PPID column so you can inspect the parent responsible for collecting the child status.

How many zombie processes are too many?

There is no universal cutoff. Compare a rising count with the applicable service or cgroup task limit and process-creation errors in logs.

Should I restart a parent that has zombie children?

Only after checking ownership and impact. Restart through the owning service supervisor when safe, since the parent may have unrelated child work or active requests.

Why do container and host show different PIDs?

Nested PID namespaces display separate identifiers. Inspect the parent from the namespace where the child is visible and check which process acts as namespace PID 1.

What should I check if worker creation fails?

Check the service logs and applicable system, service, or cgroup task limits. A process-creation error can have causes beyond zombie accumulation.

Does SIGCHLD reap a zombie by itself?

No. SIGCHLD notifies the parent about child state. A wait-family call collects the status unless the program deliberately uses automatic reaping behavior.

Can I use htop to find zombie processes?

Yes, if it is installed. Press F5 for tree view and use F2 setup to add STATE and PPID columns if needed. The manual defines Z as zombie; avoid F9 unless you intend to signal the selected process.