Skip to main content

Namespace Stuck Terminating

Before You Change Anything

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 UserSwarm custom resource still has a finalizer, but Metacontroller or the userswarm webhook is unavailable.
  • Kubernetes API aggregation layer resources are blocking deletion.
1
Step 1

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.

2
Step 2

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"}]'
3
Step 3

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 -
4
Step 4

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 stale e2e-* resources automatically. For shared namespaces, manual cleanup is still sensitive and should be rare.

Quick Reference

StepCommand
Check stuck namespaceskubectl get ns | grep Terminating
Check blocking resourceskubectl get all -n <namespace>
Remove resource finalizerskubectl patch <kind> <name> -n <ns> --type json -p '[{"op":"remove","path":"/metadata/finalizers"}]'
Force-remove namespace finalizerskubectl get ns <ns> -o json | python3 ... | kubectl replace --raw ... (see above)
Verify deletionkubectl get ns <namespace>

What's next: Return to the Developer Guides index or explore the Troubleshooting Reference for additional scenarios.