Namespace Stuck Terminating
Start with inspection and narrowing steps first. Some fixes in debugging pages mutate shared resources, so separate observation from recovery.
A namespace stuck in Terminating blocks cleanup and can prevent redeployment of shared platform resources.
Symptoms
kubectl get ns
Output shows:
NAME STATUS AGE
userswarms Terminating 45m
The namespace has been in Terminating state for more than a few minutes and is not progressing.
Cause
Finalizers on the namespace or its child resources prevent Kubernetes from completing the deletion. Common causes:
- A CRD operator was removed before its custom resources were cleaned up. Orphaned finalizers cannot be processed because the controller that handles them no longer exists.
- A cluster-scoped
UserSwarmcustom resource still has a finalizer, but Metacontroller or the userswarm webhook is unavailable. - Kubernetes API aggregation layer resources are blocking deletion.
Check what is blocking deletion
List the resources still present in the namespace.
kubectl api-resources --verbs=list --namespaced -o name | while read resource; do
kubectl get "$resource" -n <namespace> 2>/dev/null | grep -v "^$" && echo "--- $resource ---"
done
Any remaining object with finalizers can block namespace deletion.
Remove child finalizers
For each blocking object, remove its finalizers.
kubectl patch <kind> <name> -n <namespace> --type json \
-p '[{"op":"remove","path":"/metadata/finalizers"}]'
For a cluster-scoped UserSwarm:
kubectl patch userswarm <name> --type json \
-p '[{"op":"remove","path":"/metadata/finalizers"}]'
Force-remove namespace finalizers
If the namespace itself is still stuck, clear its finalizers directly.
kubectl get ns <namespace> -o json | python3 -c "
import json,sys; ns=json.load(sys.stdin); ns['spec']['finalizers']=[]; json.dump(ns,sys.stdout)
" | kubectl replace --raw "/api/v1/namespaces/<namespace>/finalize" -f -
Verify deletion
Confirm the namespace is gone.
kubectl get ns <namespace>
It should no longer appear in the output.
Prevention
- Always delete custom resources before removing the controllers that reconcile them.
- If deleting a
UserSwarm, ensure Metacontroller and the userswarm webhook are running before triggering deletion:
kubectl get pods -n userswarm-controller
kubectl get pods -n backend | grep userswarm-webhook
- The reaper CronJob (
crawbl platform userswarm reaper --max-age=2h) handles stalee2e-*resources automatically. For shared namespaces, manual cleanup is still sensitive and should be rare.
Quick Reference
| Step | Command |
|---|---|
| Check stuck namespaces | kubectl get ns | grep Terminating |
| Check blocking resources | kubectl get all -n <namespace> |
| Remove resource finalizers | kubectl patch <kind> <name> -n <ns> --type json -p '[{"op":"remove","path":"/metadata/finalizers"}]' |
| Force-remove namespace finalizers | kubectl get ns <ns> -o json | python3 ... | kubectl replace --raw ... (see above) |
| Verify deletion | kubectl get ns <namespace> |
What's next: Return to the Developer Guides index or explore the Troubleshooting Reference for additional scenarios.