How to fix ArgoCD finalizer stuck in Kubernetes

KubernetesINTERMEDIATEHIGHUpdated Dec 6, 2025· 145 views

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.

Quick fix

Fixes ArgoCD finalizer stuck

kubectl get application <app-name> -n argocd -o yaml | grep -A 5 "metadata:\|finalizers:\|deletionTimestamp"
  1. Check Application deletion status and finalizers
  2. Check ArgoCD controller logs for errors
  3. Patch Application to remove the finalizer (if safe)
  4. If cascading delete is needed, restart the ArgoCD controller
kubernetes — error
kubectl get application <app-name> -n argocd -o yaml | grep -A 5 "metadata:\|finalizers:\|deletionTimestamp"
ArgoCD finalizer stuck

What this error means

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.

Typical symptoms

  • Application shows "Terminating" status indefinitely
  • kubectl delete app <name> hangs without returning
  • Application appears in kubectl get applications but won't disappear
  • Application has metadata.deletionTimestamp set
  • Application metadata shows finalizers: [resources-finalizer.argocd.argoproj.io]
  • ArgoCD controller logs show cascade delete attempts but no completion
  • Namespace cannot be deleted because Application finalizer blocks it

Common causes

  1. Cascade delete configured but ArgoCD controller is unresponsive or crashed
  2. Orphaned resources (not managed by ArgoCD) referenced by finalizer
  3. ArgoCD Application custom resource definition (CRD) has admission webhooks blocking deletion
  4. Finalizer added unintentionally without understanding cascade delete behavior
  5. Resource ownership chains broken (some child resources have conflicting owners)
  6. Network issues preventing controller from reaching cluster to delete resources
  7. Resource quotas or policies preventing cascading deletion in the cluster

How to fix "ArgoCD finalizer stuck"

1Check Application deletion status and finalizers

Verify the Application is stuck and identify which finalizers are present:

bash
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"

2Check ArgoCD controller logs for errors

Review ArgoCD controller logs to understand why cascade delete is stuck:

bash
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

3Patch Application to remove the finalizer (if safe)

If cascade delete is not needed or the controller is unresponsive, remove the finalizer:

bash
kubectl patch application <app-name> -n argocd -p '{"metadata":{"finalizers":null}}' --type merge

Verify removal:

bash
kubectl get application <app-name> -n argocd -o yaml | grep finalizers

Once 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.

4If cascading delete is needed, restart the ArgoCD controller

If you want cascade delete to complete properly, restart the controller:

bash
kubectl rollout restart deployment/argocd-application-controller -n argocd

Wait for the pod to restart:

bash
kubectl rollout status deployment/argocd-application-controller -n argocd

The controller will resume processing the deletion and attempt cascade delete. Monitor logs:

bash
kubectl logs -n argocd deployment/argocd-application-controller -f
5Check for stuck child resources blocking deletion

If cascade delete completes but the finalizer remains, check for resources with their own finalizers:

bash
# 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:

bash
kubectl patch pvc <pvc-name> -p '{"metadata":{"finalizers":null}}' --type merge
6Use kubectl delete with --ignore-not-found for force deletion

As a last resort, force delete the Application using the grace period override:

bash
kubectl delete application <app-name> -n argocd --grace-period=0 --force

This 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

7Prevent future finalizer issues

To avoid finalizer problems in the future:

1. Only add the finalizer if cascade delete is truly needed:

bash
# Good: Add finalizer explicitly when creating app
argocd app create <app-name> --cascade

# Avoid manually adding it without understanding cascade delete

2. Use background cascade deletion (safer than foreground):

bash
argocd app create <app-name> --cascade=background

3. Ensure ArgoCD controller has sufficient resources and is monitored for crashes:

bash
kubectl top pod -n argocd | grep application-controller
kubectl describe deployment/argocd-application-controller -n argocd

Advanced notes

ArgoCD 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.

Frequently asked questions

What does "ArgoCD finalizer stuck" mean?
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.
How do I fix "ArgoCD finalizer stuck"?
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.
What causes "ArgoCD finalizer stuck"?
Cascade delete configured but ArgoCD controller is unresponsive or crashed Orphaned resources (not managed by ArgoCD) referenced by finalizer ArgoCD Application custom resource definition (CRD) has admission webhooks blocking deletion
Is the "ArgoCD finalizer stuck" error serious?
Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.

Official resources & further reading