# kubectl delete: Usage, Options & Common CI Errors

> kubectl delete removes resources by name, label, or manifest. Graceful termination, force deletes, finalizers that hang a delete, and safe scoping in CI.

Source: https://latchkey.dev/learn/command-reference/kubectl-delete  
Updated: 2026-06-25

Remove resources - and survive the finalizer that hangs the delete.

kubectl delete removes objects by name, by label selector, or by the same manifest you applied. In CI it powers teardown jobs, where scoping and timeouts matter.

## What it does

kubectl delete sends a delete request and, by default, waits for graceful termination (the object's terminationGracePeriodSeconds). You can target a name, a -l selector, a -f manifest, or --all within a namespace. --grace-period and --force control how aggressively termination happens.

## Common usage

```Terminal
kubectl delete pod my-pod
kubectl delete -f manifests/             # everything in those files
kubectl delete pods -l app=web           # by label
kubectl delete deploy web --wait=false   # do not block on teardown
kubectl delete pod stuck --grace-period=0 --force
```

## Common errors in CI

A delete that "hangs forever" in CI is almost always a finalizer: the object enters Terminating but a controller has not removed its finalizer, so kubectl blocks until your step times out. Check with kubectl get <obj> -o jsonpath='{.metadata.finalizers}'. The dangerous workaround - kubectl patch ... -p '{"metadata":{"finalizers":null}}' - orphans whatever the finalizer was cleaning up, so only do it for known-stuck test fixtures. Also beware --all with a missing -n: it deletes everything in the default namespace. Always scope teardown to a dedicated namespace and delete that namespace instead.

## Using this in CI

A runner has no kubeconfig, no cached context, and no interactive auth. Every kubectl invocation in CI needs the context supplied explicitly, and most confusing CI failures here are the command running against the wrong cluster or no cluster at all.

```Terminal
# never rely on the ambient context on a runner
kubectl --context "$KUBE_CONTEXT" -n "$NAMESPACE" get pods

# confirm what you are actually connected to before mutating anything
kubectl config current-context
kubectl cluster-info

# fail fast instead of hanging on an unreachable API server
kubectl --request-timeout=30s get nodes
```

> Always set `--request-timeout` in CI. Without it an unreachable API server hangs until the job times out, which turns a thirty-second failure into a twenty-minute one.

## FAQ

### kubectl delete: Usage, Options & Common CI Errors?

kubectl delete removes objects by name, by label selector, or by the same manifest you applied. In CI it powers teardown jobs, where scoping and timeouts matter.

### What it does?

kubectl delete sends a delete request and, by default, waits for graceful termination (the object's terminationGracePeriodSeconds). You can target a name, a -l selector, a -f manifest, or --all within a namespace. --grace-period and --force control how aggressively termination happens.

### Common errors in CI?

A delete that "hangs forever" in CI is almost always a finalizer: the object enters Terminating but a controller has not removed its finalizer, so kubectl blocks until your step times out. Check with kubectl get <obj> -o jsonpath='{.metadata.finalizers}'. The dangerous workaround - kubectl patch ...

---

Latchkey runs CI/CD that repairs its own failures. Agent entry points: https://latchkey.dev/agent.txt, https://latchkey.dev/openapi.json, https://latchkey.dev/llms.txt
