Kubernetes Namespace Stuck in Terminating Fix
In this tutorial, you'll learn about Kubernetes Namespace Stuck in Terminating Fix. We cover key concepts, practical examples, and best practices.
The Problem
Deleting a namespace hangs and the namespace stays in Terminating state:
$ kubectl delete namespace my-namespace
namespace "my-namespace" deleted
$ kubectl get namespaces
NAME STATUS AGE
my-namespace Terminating 5m
The namespace appears to be deleted but never disappears. All resources inside the namespace should have been deleted, but some resource is preventing the cleanup.
Quick Fix
Step 1: List remaining resources in the namespace
kubectl api-resources --verbs=list --namespaced -o name | xargs -n1 kubectl get -n my-namespace 2>/dev/null
This shows all namespaced resources still in the namespace. Look for custom resources, CRDs, or resources with finalizers.
Step 2: Check the namespace YAML for finalizers
kubectl get namespace my-namespace -o yaml
apiVersion: v1
kind: Namespace
metadata:
name: my-namespace
spec:
finalizers:
- kubernetes
The spec.finalizers list must be empty for the namespace to terminate. Common finalizers that get stuck:
kubernetes(Kubernetes default -- safe to remove)foregroundDeletion(waits for child resources)- Custom finalizers from operators or controllers
Step 3: Patch the namespace to remove all finalizers
WRONG -- trying to delete with finalizers in place:
kubectl delete namespace my-namespace --force --grace-period=0
This may still hang if finalizers are present.
RIGHT -- remove all finalizers with a JSON patch:
kubectl get namespace my-namespace -o json | jq '.spec.finalizers = []' | kubectl replace --raw "/api/v1/namespaces/my-namespace/finalize" -f -
Or use Python:
python3 -c "
import json, sys
ns = json.load(sys.stdin)
ns['spec']['finalizers'] = []
json.dump(ns, sys.stdout)
" < <(kubectl get namespace my-namespace -o json) | kubectl replace --raw "/api/v1/namespaces/my-namespace/finalize" -f -
Step 4: Delete stuck custom resources
If CRDs have instances in the namespace, delete them first:
kubectl delete crd --all
kubectl delete $(kubectl get crd -o name) 2>/dev/null
Then retry the namespace deletion.
Step 5: Check for APIService resources blocking deletion
kubectl get apiservice
Look for APIService resources with Available=False that reference the stuck namespace:
NAME SERVICE AVAILABLE AGE
v1beta1.example.com my-namespace/operator False 5d
Delete the problematic APIService:
kubectl delete apiservice v1beta1.example.com
Step 6: Force delete using the API directly
As a last resort, force delete through the raw Kubernetes API:
kubectl proxy &
curl -k -H "Content-Type: application/json" -X PUT \
--data '{"apiVersion":"v1","kind":"Namespace","metadata":{"name":"my-namespace"},"spec":{"finalizers":[]}}' \
http://localhost:8001/api/v1/namespaces/my-namespace/finalize
kill %1
Use DodaTech's Namespace Cleaner to identify stuck resources, remove finalizers, and force-terminate namespaces safely.
Prevention
- Always delete all resources in a namespace before deleting the namespace itself.
- Use
helm uninstallto remove Helm releases before deleting the namespace. - Avoid installing CRDs with
scope: Namespacedunless necessary. - Set
--timeoutonkubectl delete namespaceto detect hangs early. - Audit custom operators that add finalizers to resources.
Common Mistakes with namespace terminating
- Misunderstanding that
Stringis[Char]with poor performance for large text operations - Using
foldlinstead offoldl'causing stack overflow on large lists - Forgetting
deriving (Show, Eq)on custom data types needed for debugging
These mistakes appear frequently in real-world K8S code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.
Practice Exercise
Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.
This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.
FAQ
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro