ArgoCD Resource Hook Failed: How to Debug and Fix It
ArgoCD PreSync or PostSync hooks failing silently? Here's how to find the real error, fix hook job issues, and stop your deployments from getting stuck.
ArgoCD hooks — PreSync, PostSync, SyncFail — are powerful but notoriously hard to debug when they fail. The app stays in Progressing forever, or flips to Degraded with no useful message in the UI.
What a Hook Failure Looks Like
In the ArgoCD UI, you'll see:
Health Status: Degraded
Sync Status: OutOfSync
Message: Job.batch "my-pre-sync-job" is invalid
Or the hook Job just disappears after failure, taking the logs with it.
Why This Happens
The most common causes:
- Hook Job fails — pod exits non-zero, ArgoCD marks sync as failed
- Hook Job deleted before you can read logs —
argocd.argoproj.io/hook-delete-policy: HookSucceededdeletes on success, butBeforeHookCreationdeletes it before you can even see it fail - Resource quota / namespace limits — Job can't schedule pods
- Wrong hook annotation — typo in
argocd.argoproj.io/hookvalue
Step 1: Find the Failed Hook Job
# List all Jobs in the namespace
kubectl get jobs -n your-namespace
# Look for failed jobs
kubectl get jobs -n your-namespace --field-selector status.failed=1
# Get events
kubectl describe job my-pre-sync-job -n your-namespaceStep 2: Get the Logs Before They Disappear
The hook pod gets deleted after the Job completes. You need to be fast — or change the delete policy.
# While hook is running, grab logs immediately
kubectl logs -n your-namespace -l job-name=my-pre-sync-job --previous
# Or watch pods
kubectl get pods -n your-namespace -w | grep hookTo prevent auto-deletion while debugging, temporarily change the hook delete policy:
metadata:
annotations:
argocd.argoproj.io/hook: PreSync
argocd.argoproj.io/hook-delete-policy: HookFailed # only delete if it failsOr set it to Never while debugging:
argocd.argoproj.io/hook-delete-policy: NeverRemove this after you've fixed the issue.
Step 3: Common Hook Fixes
Fix 1: Hook Job exits non-zero
Check the container's exit code:
kubectl describe pod -n your-namespace -l job-name=my-pre-sync-jobLook at Exit Code in the container status. A script returning exit 1 will fail the hook.
In your hook Job spec, make sure your command is correct:
spec:
template:
spec:
containers:
- name: hook
image: bitnami/kubectl:latest
command: ["/bin/sh", "-c"]
args:
- |
kubectl apply -f /config/migration.yaml || exit 1
restartPolicy: Never # must be Never for hook JobsFix 2: ImagePullBackOff in hook pod
kubectl describe pod -n your-namespace <hook-pod-name>If the image can't be pulled, add imagePullSecrets:
spec:
template:
spec:
imagePullSecrets:
- name: ecr-registry-secretFix 3: Hook Job can't be created — resource quota
kubectl describe resourcequota -n your-namespaceIf you're hitting CPU/memory quota, reduce the hook Job's resource requests:
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "256Mi"Fix 4: ArgoCD not picking up hook annotations
Verify your annotation is on the correct resource:
apiVersion: batch/v1
kind: Job
metadata:
name: db-migration
annotations:
argocd.argoproj.io/hook: PreSync # ← must be exact
argocd.argoproj.io/hook-delete-policy: BeforeHookCreationValid hook values: PreSync, Sync, PostSync, SyncFail, Skip
Case matters — presync won't work.
Step 5: Retry a Stuck Sync
If your app is stuck in Progressing and the hook has already failed:
# Force a fresh sync
argocd app sync your-app --force
# Or terminate the in-progress operation
argocd app terminate-op your-app
argocd app sync your-appPrevent This in the Future
Add a timeout to your hook Jobs so they don't hang forever:
spec:
activeDeadlineSeconds: 120 # fail if not done in 2 min
backoffLimit: 0 # don't retry on failureEnable ArgoCD notifications so you get Slack alerts when a sync fails — saves you from discovering it hours later.
Tooling used: ArgoCD 2.x, kubectl, Kubernetes Jobs
If your hooks are database migrations, check out Flyway or Liquibase — they handle migration state properly and work well as ArgoCD PreSync hooks.
Today I Fixed
Short real fixes from production — posted daily
Stay ahead of the curve
Get the latest DevOps, Kubernetes, AWS, and AI/ML guides delivered straight to your inbox. No spam — just practical engineering content.
Related Articles
ArgoCD App of Apps Not Syncing — Every Fix (2026)
Your ArgoCD App of Apps pattern stopped syncing. Child apps aren't created, parent shows OutOfSync, or sync is stuck. Here are every cause and the exact fix.
ArgoCD Image Updater Not Syncing — Fix Guide
ArgoCD Image Updater detects a new image tag but doesn't update the Application. Here's how to diagnose and fix annotation errors, registry auth issues, write-back problems, and sync failures.
ArgoCD Application Stuck OutOfSync or Progressing: Complete Fix Guide
ArgoCD app won't sync? Stuck in OutOfSync or Progressing state forever? Here's every cause and how to fix each one step by step.