Argo CD shows two independent statuses for every Application and every resource in it.
| Sync status | Meaning |
|---|---|
| Synced | Live objects match the desired state rendered from Git |
| OutOfSync | Something differs: a new commit, a manual change, or a missing/extra object |
| Unknown | Argo CD could not compare, for example the repo is unreachable or rendering failed |
| Health status | Meaning |
|---|---|
| Healthy | The object works: Deployment rolled out, Pods ready, PVC bound, Ingress has an address |
| Progressing | Still rolling out or waiting; not failed yet |
| Degraded | Failed: crash-looping Pods, a Deployment past its progress deadline, a failed Job |
| Suspended | Paused, for example a suspended CronJob or a paused rollout |
| Missing | In Git but not in the cluster |
An app can be Synced and Degraded (Git was applied, but the new image crashes) or OutOfSync and Healthy (someone scaled it by hand, and it still works). Read both.
How Argo CD notices a change
- By default the controller polls each repo every 3 minutes (
timeout.reconciliationinargocd-cm). - A Git webhook to
https://argocd.example.com/api/webhookmakes it react within seconds. argocd app get shop-api-dev --refreshforces a new comparison now;--hard-refreshalso clears the manifest cache.
See what differs
argocd app diff shop-api-dev # unified diff: desired vs live
argocd app manifests shop-api-dev # the rendered desired manifests
argocd app resources shop-api-dev # every object with its status
argocd app history shop-api-dev # revisions that were synced, with IDs
argocd app diff exits with code 1 when there is a difference, which makes it handy in scripts and pull-request checks.
Why an app stays OutOfSync
| Symptom | Usual cause | Fix |
|---|---|---|
Diff shows replicas changing all the time |
An HPA owns the replica count | Remove replicas from Git or add ignoreDifferences (module 4) |
Fields like metadata.annotations added by a controller |
A mutating webhook or operator writes to the object | ignoreDifferences for those paths |
| Extra resource marked for deletion | It exists live but was removed from Git | Sync with prune |
| Unknown with "repository not accessible" | Credentials or network | Fix the repo credentials (module 4) |
Health for custom resources
Built-in health checks cover core kinds (Deployment, StatefulSet, Service, Ingress, PVC, Job...) and common CRDs. For your own CRDs you can add a Lua health check in argocd-cm (resource.customizations.health.<group>_<kind>), so an operator's custom object reports Healthy or Degraded too.
Habit: after every sync, run argocd app wait --health. Synced alone only proves the YAML was accepted.