ArgoCD Application Stuck In Progressing State: Debugging Sync Failures And Manual Recovery Steps
ArgoCD Application Stuck in Progressing State: Debugging Sync Failures and Manual Recovery Steps
If you've worked with ArgoCD for any meaningful amount of time, you've probably stared at that dreaded "Progressing" status, watching your application sync hang indefinitely while your deployment pipeline backs up behind it. As someone who's spent countless hours debugging these scenarios, I can tell you that ArgoCD's sync failures are often cryptic, but they're usually fixable once you know where to look.
The "Progressing" state is ArgoCD's way of saying "I'm trying, but something's not quite right." Unlike a clean failure, this limbo state can persist for hours, leaving you wondering if you should wait it out or intervene. Let's dive into the most common causes and, more importantly, how to get your deployments unstuck.
Understanding the Progressing State
ArgoCD applications get stuck in "Progressing" when the sync operation starts but can't complete successfully. This typically happens during the three-way merge process where ArgoCD compares your Git state, live cluster state, and desired state. When these don't align as expected, or when Kubernetes resources are slow to reconcile, you end up in this frustrating middle ground.
The key difference between "Progressing" and "Synced" is that ArgoCD has initiated changes but hasn't received confirmation that all resources have reached their desired state. This could be due to:
- Resource dependencies not being met
- Slow-starting containers or failed health checks
- Network policies blocking communication
- Resource quotas being exceeded
- Webhook failures or validation errors
Common Culprits Behind Sync Failures
1. Health Check Timeouts
The most frequent cause I see is applications with custom health checks that take longer than ArgoCD's default timeout. This is especially common with databases, message queues, and other stateful services that need time to initialize.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: postgres-app
spec:
syncPolicy:
syncOptions:
- CreateNamespace=true
# Increase timeout for slow-starting services
- Timeout=600s
# Custom health check configuration
ignoreDifferences:
- group: apps
kind: Deployment
jsonPointers:
- /spec/replicas
2. Resource Ordering Issues
Kubernetes doesn't guarantee resource creation order, but some applications require specific sequencing. I've seen this break ArgoCD syncs when, for example, a ConfigMap needs to exist before a Deployment references it.
# Use sync waves to control order
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
annotations:
argocd.argoproj.io/sync-wave: "2" # Deploy after wave 1
spec:
# ... deployment spec
---
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
annotations:
argocd.argoproj.io/sync-wave: "1" # Deploy first
data:
config.yaml: |
# ... config data
3. Webhook and Admission Controller Conflicts
Custom admission controllers or mutating webhooks can modify resources during creation, causing ArgoCD to see a drift between desired and actual state. This creates an endless sync loop.
# Ignore fields that webhooks commonly modify
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
spec:
ignoreDifferences:
- group: apps
kind: Deployment
jsonPointers:
- /spec/template/metadata/annotations
- /spec/template/spec/securityContext
- group: ""
kind: Service
jsonPointers:
- /spec/clusterIP
Debugging Techniques That Actually Work
1. Use ArgoCD CLI for Real-time Insights
The web UI is pretty, but the CLI gives you the raw details you need for debugging:
# Get detailed sync status
argocd app get my-app --show-operation
# Watch sync progress in real-time
argocd app sync my-app --async
argocd app wait my-app --timeout 300
# Get detailed resource status
argocd app resources my-app --output wide
2. Examine Resource Events
Kubernetes events are goldmines for debugging sync issues:
# Check events for the application namespace
kubectl get events -n my-app-namespace --sort-by='.lastTimestamp'
# Focus on warning and error events
kubectl get events -n my-app-namespace --field-selector type=Warning
# Get events for specific resources
kubectl describe deployment my-app -n my-app-namespace
3. Analyze ArgoCD Controller Logs
The application controller logs contain detailed information about why syncs fail:
# Get ArgoCD application controller logs
kubectl logs -n argocd -l app.kubernetes.io/name=argocd-application-controller -f
# Filter for your specific application
kubectl logs -n argocd -l app.kubernetes.io/name=argocd-application-controller | grep "my-app"
Look for patterns like:
- "failed to sync application"
- "health check failed"
- "hook failed"
- "timeout"
Manual Recovery Strategies
1. Force Refresh and Hard Sync
Sometimes ArgoCD just needs a gentle push to reassess the situation:
# Force refresh the application state
argocd app get my-app --refresh --hard-refresh
# Perform a hard sync (ignore differences)
argocd app sync my-app --force --replace
The --replace flag tells ArgoCD to delete and recreate resources rather than trying to patch them. Use this carefully, especially with stateful resources.
2. Selective Resource Sync
When only specific resources are problematic, sync them individually:
# Sync only specific resources
argocd app sync my-app --resource apps:Deployment:my-app-deployment
argocd app sync my-app --resource v1:Service:my-app-service
# Skip problematic resources temporarily
argocd app sync my-app --resource-exclude apps:Deployment:problematic-deployment
3. Reset Application State
For severely stuck applications, sometimes you need to reset the sync state entirely:
# Terminate any ongoing sync operations
argocd app terminate-op my-app
# Reset the application to a clean state
argocd app delete my-app --cascade=false
argocd app create -f my-app.yaml
Preventive Measures and Best Practices
1. Implement Proper Health Checks
Don't rely on ArgoCD's default health checks for complex applications. Define custom health checks that actually verify your service is ready:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
spec:
# Custom health check
healthCheck:
httpHeaders:
- name: Accept
value: application/json
path: /health
port: 8080
scheme: HTTP
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
2. Use Sync Waves and Hooks Strategically
Plan your resource deployment order using sync waves and implement hooks for critical operations:
# Pre-sync hook for database migration
apiVersion: batch/v1
kind: Job
metadata:
name: db-migration
annotations:
argocd.argoproj.io/hook: PreSync
argocd.argoproj.io/hook-delete-policy: BeforeHookCreation
spec:
template:
spec:
containers:
- name: migrate
image: my-app:latest
command: ["python", "manage.py", "migrate"]
restartPolicy: Never
3. Configure Reasonable Timeouts
Set appropriate timeouts based on your application characteristics:
apiVersion: argoproj.io/v1alpha1
kind: Application
spec:
syncPolicy:
syncOptions:
- Timeout=300s # 5 minutes for most apps
# For databases or complex services:
# - Timeout=900s # 15 minutes
retry:
limit: 3
backoff:
duration: 30s
factor: 2
maxDuration: 5m
When to Seek Help vs. When to Force
Knowing when to wait and when to intervene is crucial. Here's my rule of thumb:
Wait it out if:
- It's been less than your configured timeout
- Logs show progress (pods starting, health checks running)
- This is a known slow-starting service
Intervene if:
- Sync has been progressing for more than 2x your expected deployment time
- Error logs show clear failures (image pull errors, resource conflicts)
- Resource events indicate quota or permission issues
- Other deployments are backing up behind this one
Wrapping Up
ArgoCD's "Progressing" state doesn't have to be a deployment killer. With the right debugging techniques and recovery strategies, you can quickly identify the root cause and get your applications back on track. The key is understanding that ArgoCD is usually stuck for a reason – it's trying to protect you from deploying broken configurations.
Remember: ArgoCD is conservative by design. It would rather wait and be safe than deploy something that might break your production environment. Most of the time, that "stuck" sync is ArgoCD doing its job. Your job is to figure out why it can't complete and give it the help it needs.
The debugging techniques and recovery steps I've outlined here have saved me countless hours of frustration. Keep them in your toolkit, and you'll find that those mysterious "Progressing" states become much less mysterious – and much less stressful.
Was this article helpful?
Data Infrastructure Engineer
Your data is only as good as the infrastructure it sits on. I specialize in PostgreSQL, Redis, database migrations, backup strategies, and making sure your data survives whatever chaos your application throws at it.
Related Articles
ArgoCD Application Stuck In Progressing State: Diagnosing And Fixing Sync Failures
If you've worked with ArgoCD for more than five minutes, you've probably encountered this frustrating scenario: your application gets stuck in a "Progressi...
Backstage TechDocs Not Rendering: Fixing MkDocs Build Failures And Missing Plugin Errors
TechDocs is one of the most powerful features in Backstage — the idea of docs-as-code, living right next to your services in a unified developer portal, is...
Implementing Internal Developer Platform Golden Paths With Backstage Software Templates
If you've ever watched a new developer spend three days just getting a service scaffolded, configured, and deployed to a non-production environment, you un...
Backstage Developer Portal Setup for Platform Teams
How to set up Spotify's Backstage as a developer portal — software catalog, templates, and TechDocs for platform teams that want to scale.
Crossplane: Managing Cloud Infrastructure from Kubernetes
How to use Crossplane to provision and manage cloud infrastructure using Kubernetes-native APIs — one control plane to rule them all.
Pulumi vs Terraform: An Honest Comparison from the Trenches
A real-world comparison of Pulumi and Terraform — where each shines, where each hurts, and how to pick the right one for your team.
More in Platform Engineering
View all →DevOps Team Onboarding Checklist: Get New Engineers Productive in Week One
A practical week-one DevOps onboarding checklist covering access, tooling, pipelines, and culture to get new engineers contributing fast.