How to fix ArgoCD hook failed in Kubernetes

KubernetesINTERMEDIATEHIGHUpdated Dec 6, 2025ยท 158 views

ArgoCD sync operations hang or fail when resource hooks (PreSync, PostSync, Sync, SyncFail) encounter errors, timeouts, or resource conflicts. Causes include Jobs getting deleted before completion, immutable field errors, hook timeout mismatches, or unfinished hook resources. Fix by adjusting ttlSecondsAfterFinished, using proper delete policies, implementing health checks, and debugging hook resource status.

Quick fix

Fixes ArgoCD hook failed

# Or query via CLI
kubectl get job -A | grep -E "presync|postsync|sync-hook"
kubectl describe job <hook-job-name> -n <namespace>
  1. Check hook resource status in ArgoCD UI
  2. Set proper ttlSecondsAfterFinished on hook Jobs
  3. Apply correct hook-delete-policy
  4. Use correct hook type for your use case
kubernetes โ€” error
# Or query via CLI
kubectl get job -A | grep -E "presync|postsync|sync-hook"
kubectl describe job <hook-job-name> -n <namespace>
ArgoCD hook failed

What this error means

ArgoCD hooks are Kubernetes resources (Jobs, Pods, etc.) annotated with argocd.argoproj.io/hook that run before, during, or after a sync operation. When a hook fails, times out, or becomes stuck in a pending state, the entire sync operation is blocked. This typically happens because hook resources are not completing successfully, ArgoCD cannot detect completion, or subsequent hook phases cannot proceed due to resource conflicts. Understanding hook lifecycle and deletion policies is critical to debugging sync failures.

Typical symptoms

  • Sync operation stuck in "Running" or "Waiting for hook completion" state
  • ArgoCD UI shows hook resource failing or pending indefinitely
  • PreSync/PostSync/Sync hooks not triggering at all
  • Job resources deleted before hook completion can be detected
  • Error: "Field is immutable" when hook Jobs are being re-synced
  • Multiple sync attempts deleting and re-creating hook resources
  • Hooks pass locally but fail in ArgoCD sync

Common causes

  1. Job has ttlSecondsAfterFinished=0 or very low value, deleted before ArgoCD detects completion
  2. Hook resource never reaches success state (Job/Pod fails or times out)
  3. Immutable field error in hook Jobs when re-synced (no BeforeHookCreation delete policy)
  4. Hook timeout too short relative to actual job duration
  5. Helm hooks (helm.sh/hook) not translated to ArgoCD hooks properly
  6. Missing or incorrect hook-delete-policy annotation
  7. Hook resources in different sync wave blocking later waves
  8. ArgoCD stuck hook bug where sync never completes despite resource success

How to fix "ArgoCD hook failed"

1Check hook resource status in ArgoCD UI

Navigate to your Application > Sync Result tab to see hook execution status:

bash
# Or query via CLI
kubectl get job -A | grep -E "presync|postsync|sync-hook"
kubectl describe job <hook-job-name> -n <namespace>

Look for: Completed/Failed/Pending/Unknown states. Check job logs:

bash
kubectl logs job/<hook-job-name> -n <namespace>
2Set proper ttlSecondsAfterFinished on hook Jobs

Prevent Jobs from being deleted before ArgoCD detects completion:

yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: presync-migration
  annotations:
    argocd.argoproj.io/hook: PreSync
    argocd.argoproj.io/hook-delete-policy: BeforeHookCreation,HookSucceeded
spec:
  ttlSecondsAfterFinished: 60  # Allow 60 seconds for detection
  backoffLimit: 1
  template:
    spec:
      containers:
      - name: migrator
        image: my-migration:latest
        command: ["./migrate.sh"]
      restartPolicy: Never

Minimum recommended: 60 seconds. Higher values if hook takes longer to complete.

3Apply correct hook-delete-policy

Delete policies control when hook resources are cleaned up:

yaml
metadata:
  annotations:
    argocd.argoproj.io/hook: PreSync
    argocd.argoproj.io/hook-delete-policy: BeforeHookCreation,HookSucceeded

Delete policies:
- BeforeHookCreation: Delete resource before creating new one (prevents immutable field errors)
- HookSucceeded: Delete after hook succeeds
- HookFailed: Delete if hook fails

Recommended for Jobs: BeforeHookCreation,HookSucceeded. Do NOT use alone without one of the completion policies.

4Use correct hook type for your use case

Ensure hook timing aligns with your workflow:

yaml
# Run before any resources sync
argocd.argoproj.io/hook: PreSync

# Run after main resources synced
argocd.argoproj.io/hook: PostSync

# Run during main sync (between PreSync and PostSync)
argocd.argoproj.io/hook: Sync

# Run only if sync fails
argocd.argoproj.io/hook: SyncFail

Common pattern: PreSync for schema migrations, Sync for main deployment, PostSync for tests/verification.

5Check hook resource health and timeouts

Verify the hook resource itself is healthy:

bash
kubectl get job <job-name> -n <namespace> -o jsonpath="{.status}"

# Check pod logs for failures
kubectl get pods -l job-name=<job-name> -n <namespace>
kubectl logs <pod-name> -n <namespace>

# Check for timeout issues
kubectl describe job <job-name> -n <namespace> | grep -i "timeout\|backoff"

Ensure:
- Job completes successfully (Succeeded=1)
- Pod exits with code 0
- Active pods count reaches 0
- No backoff warnings

6Enable ServerSideApply for immutable field errors

If hooks fail with "Field is immutable" errors:

yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app
spec:
  syncPolicy:
    syncOptions:
    - ServerSideApply=true
    - ApplyOutOfSyncOnly=true

ServerSideApply allows updating objects without recreating them. Combined with ApplyOutOfSyncOnly, prevents unnecessary hook re-runs.

7Verify hook waves and dependencies

Use sync waves to control hook execution order:

yaml
metadata:
  annotations:
    argocd.argoproj.io/hook: PreSync
    argocd.argoproj.io/sync-wave: "0"  # Runs first
    argocd.argoproj.io/hook-delete-policy: BeforeHookCreation,HookSucceeded
---
metadata:
  annotations:
    argocd.argoproj.io/hook: Sync
    argocd.argoproj.io/sync-wave: "1"  # Runs after wave 0

Waves ensure hooks complete before dependent resources deploy. Default wave is 0.

Advanced notes

Common pitfall: Jobs without ttlSecondsAfterFinished or with 0 value get cleaned up immediately, causing ArgoCD sync to get stuck in hook phase (Issue #21055). Always set reasonable ttl values. If using Helm charts with helm.sh/hook annotations, these are not automatically translated to ArgoCD hooksโ€”you must explicitly annotate for ArgoCD. For critical hooks in production, use SyncFail hooks to handle hook failures gracefully. PostSync hooks getting stuck may indicate resource creation/deletion loops; use hook-delete-policy carefully. Rootless deployments or restrictive RBAC may prevent hook execution; verify service account permissions. See official ArgoCD resource hooks documentation for latest fixes and known issues.

Frequently asked questions

What does "ArgoCD hook failed" mean?
io/hook that run before, during, or after a sync operation. When a hook fails, times out, or becomes stuck in a pending state, the entire sync operation is blocked. This typically happens because hook resources are not completing successfully, ArgoCD cannot detect completion, or subsequent hook phases cannot proceed due to resource conflicts.
How do I fix "ArgoCD hook failed"?
ArgoCD sync operations hang or fail when resource hooks (PreSync, PostSync, Sync, SyncFail) encounter errors, timeouts, or resource conflicts. Causes include Jobs getting deleted before completion, immutable field errors, hook timeout mismatches, or unfinished hook resources. Fix by adjusting ttlSecondsAfterFinished, using proper delete policies, implementing health checks, and debugging hook resource status.
What causes "ArgoCD hook failed"?
Job has ttlSecondsAfterFinished=0 or very low value, deleted before ArgoCD detects completion Hook resource never reaches success state (Job/Pod fails or times out) Immutable field error in hook Jobs when re-synced (no BeforeHookCreation delete policy)
Is the "ArgoCD hook failed" 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