An ArgoCD Application cannot be deleted because its finalizer is preventing deletion. The resources-finalizer.argocd.argoproj.io finalizer blocks deletion until cascade delete completes or is removed. Fix by removing the finalizer, checking for stuck resources, or patching the Application metadata.
When an ArgoCD Application has the resources-finalizer.argocd.argoproj.io finalizer, Kubernetes adds a metadata.deletionTimestamp but does not fully delete the Application until the finalizer is removed. If the finalizer never completes (cascade delete hangs or controller becomes unresponsive), the Application remains in a terminating state indefinitely. This blocks Application deletion and prevents cleanup of managed resources.
Verify the Application is stuck and identify which finalizers are present:
kubectl get application <app-name> -n argocd -o yaml | grep -A 5 "metadata:\|finalizers:\|deletionTimestamp"Look for:
- metadata.deletionTimestamp present (indicates deletion was requested)
- metadata.finalizers containing resources-finalizer.argocd.argoproj.io
- Application status showing "Terminating"
Review ArgoCD controller logs to understand why cascade delete is stuck:
kubectl logs -n argocd deployment/argocd-application-controller -f | grep -i "finalizer\|error\|<app-name>"Look for:
- "finalizer not removed" messages
- Resource deletion timeouts
- Permission denied errors
- Controller crashes or restarts
If cascade delete is not needed or the controller is unresponsive, remove the finalizer:
kubectl patch application <app-name> -n argocd -p '{"metadata":{"finalizers":null}}' --type mergeVerify removal:
kubectl get application <app-name> -n argocd -o yaml | grep finalizersOnce the finalizer is removed, the Application will be deleted immediately. Note: This does NOT cascade delete the managed resources—they will remain in the cluster.
If you want cascade delete to complete properly, restart the controller:
kubectl rollout restart deployment/argocd-application-controller -n argocdWait for the pod to restart:
kubectl rollout status deployment/argocd-application-controller -n argocdThe controller will resume processing the deletion and attempt cascade delete. Monitor logs:
kubectl logs -n argocd deployment/argocd-application-controller -fIf cascade delete completes but the finalizer remains, check for resources with their own finalizers:
# List all resources managed by the Application
kubectl get all -l argocd.argoproj.io/instance=<app-name> -o yaml | grep -B 5 "finalizers:"
# Check for common stuck resources
kubectl get pvc,pv,endpoints -o yaml | grep -B 10 "finalizers:"Manually remove finalizers from stuck resources:
kubectl patch pvc <pvc-name> -p '{"metadata":{"finalizers":null}}' --type mergeAs a last resort, force delete the Application using the grace period override:
kubectl delete application <app-name> -n argocd --grace-period=0 --forceThis performs an immediate deletion without waiting for finalizers. Resources will remain in the cluster. Use only when:
- ArgoCD controller is permanently unavailable
- The Application cannot be recovered
- You understand cascade delete will not complete
To avoid finalizer problems in the future:
1. Only add the finalizer if cascade delete is truly needed:
# Good: Add finalizer explicitly when creating app
argocd app create <app-name> --cascade
# Avoid manually adding it without understanding cascade delete2. Use background cascade deletion (safer than foreground):
argocd app create <app-name> --cascade=background3. Ensure ArgoCD controller has sufficient resources and is monitored for crashes:
kubectl top pod -n argocd | grep application-controller
kubectl describe deployment/argocd-application-controller -n argocdArgoCD finalizers implement cascading deletion: when an Application with resources-finalizer.argocd.argoproj.io is deleted, the controller attempts to delete all child resources it manages. Foreground deletion waits for child resources to be fully deleted before removing the finalizer; background deletion removes the finalizer immediately and deletes children in the background. Never remove finalizers on production Applications unless cascade delete is undesired and you understand the consequences (orphaned resources in your cluster). Some environments (especially with restrictive RBAC or network policies) may prevent the controller from deleting resources, causing the finalizer to hang indefinitely. In such cases, restart the controller or temporarily patch the RBAC to allow deletion. Always understand why an Application has a finalizer before removing it.
Failed to connect to server: connection refused (HTTP/2)
How to fix "HTTP/2 connection refused" error in Kubernetes
missing request for cpu in container
How to fix "missing request for cpu in container" in Kubernetes HPA
error: invalid configuration
How to fix "error: invalid configuration" in Kubernetes
etcdserver: cluster ID mismatch
How to fix "etcdserver: cluster ID mismatch" in Kubernetes
running with swap on is not supported
How to fix "running with swap on is not supported" in kubeadm