ArgoCD Application Stuck In Progressing State: Diagnosing And Fixing Sync Failures
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 "Progressing" state, endlessly syncing but never quite making it to "Healthy." As someone who's debugged countless ArgoCD deployments (and the cloud costs associated with their failures), I can tell you that these sync failures are often more nuanced than they appear.
Let me walk you through a systematic approach to diagnosing and fixing these issues, because every minute your application spends stuck in limbo is money down the drain.
Understanding ArgoCD's Application States
Before diving into troubleshooting, let's establish what "Progressing" actually means in ArgoCD's context:
- Sync Status: OutOfSync → Syncing → Synced
- Health Status: Progressing → Healthy/Degraded
When an application is stuck "Progressing," it typically means ArgoCD successfully applied your manifests to the cluster, but the resources aren't reaching their desired state. This is different from sync failures, where ArgoCD can't even apply the resources.
The Most Common Culprits
1. Resource Quotas and Limits
This is the silent killer of deployments. Your pods might be pending because there aren't enough resources available.
# Check current resource usage
kubectl describe nodes
kubectl get pods --all-namespaces --field-selector=status.phase=Pending
# Look for resource quota issues
kubectl describe quota -n your-namespace
I've seen entire dev environments grind to a halt because someone deployed a memory-hungry application that consumed all available cluster resources. Always check your resource quotas first.
2. ImagePullBackOff and Image Issues
# Quick check for image pull issues
kubectl get pods -n your-namespace
kubectl describe pod <pod-name> -n your-namespace
# Look for events like:
# Failed to pull image "your-registry/app:latest": rpc error: code = Unknown
Pro tip: If you're using private registries, ensure your image pull secrets are correctly configured and haven't expired. I've seen production deployments fail because someone forgot to rotate registry credentials.
Systematic Debugging Approach
Step 1: Check ArgoCD Application Details
Start by examining the application in ArgoCD's UI or CLI:
# Get application status
argocd app get your-application
# Check application events
argocd app logs your-application --follow
# Look at the sync status
argocd app sync-status your-application
Step 2: Examine Kubernetes Resources Directly
# Get all resources in the namespace
kubectl get all -n your-namespace
# Check for any failed or pending resources
kubectl get pods -n your-namespace --field-selector=status.phase!=Running
# Describe problematic resources
kubectl describe pod <failing-pod> -n your-namespace
Step 3: Review Resource Events
Kubernetes events often contain the smoking gun:
# Get recent events
kubectl get events -n your-namespace --sort-by=.metadata.creationTimestamp
# Filter events for specific resources
kubectl get events -n your-namespace --field-selector involvedObject.name=your-deployment
Common Fixes and Solutions
Fix 1: Health Check Configuration
ArgoCD might think your application is progressing when it's actually healthy. This often happens with custom resources or applications that don't have standard Kubernetes health indicators.
# Add health check configuration to your ArgoCD Application
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: your-app
spec:
# ... other config
syncPolicy:
syncOptions:
- CreateNamespace=true
- PruneLast=true
# Custom health check
ignoreDifferences:
- group: apps
kind: Deployment
jsonPointers:
- /spec/replicas
# Add resource customizations
source:
plugin:
env:
- name: ARGOCD_APP_PARAMETERS
value: |
- name: health.check.timeout
value: "300s"
Fix 2: Handling StatefulSets and Persistent Volumes
StatefulSets are notorious for getting stuck in progressing states, especially when dealing with persistent volumes:
# Check PVC status
kubectl get pvc -n your-namespace
# Look for pending PVCs
kubectl describe pvc <pvc-name> -n your-namespace
# Check if storage class exists and is properly configured
kubectl get storageclass
If PVCs are stuck in pending state:
# Ensure your storage class is set as default if needed
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast-ssd
annotations:
storageclass.kubernetes.io/is-default-class: "true"
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp3
fsType: ext4
Fix 3: Deployment Strategy Issues
Sometimes the issue is with your deployment strategy itself:
# Use rolling updates with proper configuration
apiVersion: apps/v1
kind: Deployment
metadata:
name: your-app
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0 # Ensure zero downtime
template:
spec:
containers:
- name: app
image: your-app:v1.2.3
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
Advanced Debugging Techniques
Using ArgoCD CLI for Deep Inspection
# Get detailed sync information
argocd app get your-application -o yaml
# Check resource differences
argocd app diff your-application
# Force refresh application state
argocd app refresh your-application
# Manual sync with prune
argocd app sync your-application --prune
Analyzing Resource Hooks
ArgoCD hooks can cause applications to get stuck. Check for PreSync or PostSync hooks that might be failing:
# Example of a problematic hook
apiVersion: batch/v1
kind: Job
metadata:
name: database-migration
annotations:
argocd.argoproj.io/hook: PreSync
argocd.argoproj.io/hook-delete-policy: BeforeHookCreation
spec:
template:
spec:
containers:
- name: migrate
image: migrate/migrate:latest
command: ["migrate", "-path", "/migrations", "-database", "$DATABASE_URL", "up"]
restartPolicy: Never
If this job fails, your entire application deployment will be stuck.
Prevention Strategies
1. Implement Proper Resource Requests and Limits
# Always set resource requests and limits
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
2. Configure Appropriate Timeouts
# In your ArgoCD Application
spec:
syncPolicy:
syncOptions:
- CreateNamespace=true
automated:
prune: true
selfHeal: true
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3m
3. Use Progressive Delivery
Instead of deploying everything at once, consider using ArgoCD with progressive delivery tools:
# Example Rollout resource for canary deployments
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: your-app
spec:
replicas: 5
strategy:
canary:
steps:
- setWeight: 20
- pause: {}
- setWeight: 40
- pause: {duration: 10s}
- setWeight: 60
- pause: {duration: 10s}
- setWeight: 80
- pause: {duration: 10s}
selector:
matchLabels:
app: your-app
template:
metadata:
labels:
app: your-app
spec:
containers:
- name: your-app
image: your-app:latest
Monitoring and Alerting
Set up proper monitoring to catch these issues early:
# Prometheus alerting rule for stuck ArgoCD applications
groups:
- name: argocd.rules
rules:
- alert: ArgocdAppProgressing
expr: argocd_app_health_status{health_status="Progressing"} > 0
for: 10m
labels:
severity: warning
annotations:
summary: "ArgoCD application {{ $labels.name }} stuck in Progressing state"
description: "Application {{ $labels.name }} has been in Progressing state for more than 10 minutes"
The Cost Impact
From a cost optimization perspective, applications stuck in progressing states are expensive because:
- Resource waste: Pods might be consuming resources while not serving traffic
- Developer time: Engineers spend hours debugging instead of building features
- Delayed deployments: Features don't reach customers, impacting business value
Every time I've helped teams resolve these issues systematically, they've seen immediate improvements in both deployment reliability and cost efficiency.
Final Thoughts
ArgoCD application sync failures are rarely mysterious once you know where to look. Start with the basics: resource availability, image accessibility, and proper health checks. Most issues fall into these categories, and a systematic debugging approach will save you hours of frustration.
Remember, the goal isn't just to get your application unstuck—it's to build resilient deployment pipelines that don't get stuck in the first place. Invest time in proper resource management, monitoring, and progressive delivery strategies. Your future self (and your cloud bill) will thank you.
Was this article helpful?
Related Articles
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...
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.