## TL;DR
A pod stuck in Terminating is almost always waiting on a finalizer: some controller registered cleanup work that never completes. Find the finalizer, figure out which controller owns it, and fix or remove the blocker. Force-deleting the pod without understanding the finalizer just orphans the external resource it was protecting.

## The query
```text
how to debug a stuck terminating pod (finalizers)
```

## Use this when
- kubectl delete hangs and the pod stays in Terminating
- A namespace cannot finish deleting
- Pods linger in Terminating after a controller was removed
- You are cleaning up after uninstalling an operator

## Not for when
- Pods stuck in Pending, CrashLoopBackOff, or other states
- Node-level issues (kubelet down shows as Terminating too, different fix)
- Normal graceful termination that just takes a while

## Steps

### Step 1: Look at the pod's finalizers list
Get the pod as JSON and read the finalizers array. Each entry names the controller that asked to run cleanup before deletion. No finalizers plus stuck terminating usually means the kubelet or node is the problem, not finalizers.
Expected output: a named finalizer pointing at a specific controller, or confirmation there are none.

### Step 2: Check whether the owning controller is alive
Finalizers only clear when their controller processes the deletion. If the operator or controller was uninstalled or is crashed, the finalizer waits forever. Check that the controller's pods are running.
Expected output: the controller is running (then investigate why it is not processing) or it is gone (then decide on manual cleanup).

### Step 3: Check what the finalizer is protecting
Common cases: a load balancer or volume the controller must delete first, or a custom resource with external state. Look at the controller's logs for errors during deletion; they usually say exactly what failed.
Expected output: the specific external resource or API call that is blocking deletion.

### Step 4: Fix the blocker, then let deletion proceed
Fix the underlying issue (restore the controller, fix its permissions, delete the blocking external resource manually) and watch the pod terminate cleanly. This is always preferable to force deletion.
Expected output: the finalizer clears on its own and the pod disappears.

### Step 5: As a last resort, remove the finalizer deliberately
If the controller is permanently gone and you have manually cleaned up the external resource, you can patch the pod to remove the finalizer. Do this knowingly: you are telling Kubernetes the cleanup happened.
Expected output: the pod deletes immediately. Document what external state you cleaned up by hand.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_6qMX0pkh45wXYyoRxQuhTA
