How to Fix a Kubernetes Namespace Stuck in Terminating State
In this tutorial, you'll learn about How to Fix a Kubernetes Namespace Stuck in Terminating State. We cover key concepts, practical examples, and best practices.
The Problem
You run kubectl delete namespace my-namespace and it hangs forever with Terminating status. Running kubectl get namespaces shows the namespace stuck in Terminating for minutes or hours. This happens when resources inside the namespace have finalizers that block deletion, webhooks that are now unreachable, or the namespace controller itself can't clean up dependent resources.
Quick Fix
1. Check which resources are blocking
kubectl get all -n my-namespace
kubectl get validatingwebhookconfigurations -A
kubectl get mutatingwebhookconfigurations -A
If a webhook configuration references the stuck namespace or a service within it, that webhook prevents namespace deletion. Remove any webhook configurations that reference the stuck namespace:
kubectl delete validatingwebhookconfiguration my-webhook
kubectl delete mutatingwebhookconfiguration my-webhook
2. Remove finalizers from the namespace
Get the namespace JSON and remove the finalizers array:
kubectl get namespace my-namespace -o json > ns.json
Edit ns.json to remove the "finalizers": [...] line (or set it to "finalizers": []), then apply:
kubectl replace --raw "/api/v1/namespaces/my-namespace/finalize" -f ./ns.json
3. Force delete using the API directly (one-liner)
kubectl proxy &
curl -k -H "Content-Type: application/json" -X PUT \
--data-binary '{"kind":"Namespace","apiVersion":"v1","metadata":{"name":"my-namespace"},"spec":{"finalizers":[]}}' \
http://127.0.0.1:8001/api/v1/namespaces/my-namespace/finalize
kill %1
4. Quick one-liner for force deletion
kubectl get namespace my-namespace -o json | tr -d "\n" | sed "s/\"finalizers\": \[[^]]\+\]/\"finalizers\": []/" | kubectl replace --raw /api/v1/namespaces/my-namespace/finalize -f -
5. Verify the namespace was removed
kubectl get namespaces | grep my-namespace
If the namespace no longer appears, the fix was successful. If it's still visible, repeat the steps or check for leftover resources that may be recreating the finalizers.
6. Patch the namespace as an alternative
kubectl patch namespace my-namespace -p '{"metadata":{"finalizers":[]}}' --type=merge
Common Causes
| Cause | Why It Gets Stuck | Fix |
|---|---|---|
| Finalizers on resources | Namespace controller waits for finalizer removal | Remove finalizers from the namespace |
| Webhooks that reference the namespace | Webhook is unreachable, blocking deletion | Delete the webhook configuration |
| CRDs with instances in the namespace | Custom resources prevent cleanup | Delete CRD instances first |
| Controller loop recreating resources | A controller recreates deleted resources | Scale the controller to 0 |
Use kubectl describe for Detailed Diagnostics
kubectl describe pod <pod-name>
# Events:
# Type Reason Age From Message
# ---- ------ ---- ---- -------
# Warning BackOff 5m kubelet Back-off restarting failed container
The Events section at the bottom of kubectl describe output is the most valuable diagnostic tool. It shows a chronological log of scheduling failures, image pull errors, and container crashes.
Prevention
- Delete all resources in a namespace first before deleting the namespace itself
- Use
kubectl delete all --all -n my-namespaceto clear resources first - Avoid custom finalizers unless absolutely necessary
- Delete webhook configurations before their target namespaces
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro