Skip to content
Latchkey

Argo CD app stuck "OutOfSync" not converging in CI

An Application reports OutOfSync when live state differs from the target revision in Git. If it stays OutOfSync after a sync, something in the cluster keeps mutating the resource back, or Argo CD is diffing a field the cluster sets itself.

What this error means

argocd app sync reports success but the Application immediately returns to OutOfSync, or a CI argocd app wait --sync never sees Synced and eventually times out.

argocd
Name:               my-app
Sync Status:        OutOfSync from HEAD (a1b2c3d)
GROUP  KIND        NAMESPACE  NAME     STATUS     HEALTH
apps   Deployment  prod       api      OutOfSync  Progressing

Diagnose it: state, credentials, or drift?

Infrastructure failures in CI are usually about state access or credentials rather than the configuration itself. Confirm the runner can reach and lock state before reading the plan output.

Terminal
terraform init -backend=true -input=false
terraform providers
terraform plan -input=false -no-color -detailed-exitcode
#   exit 0 = no changes, 2 = changes present, 1 = error

Common causes

A controller or webhook mutates the resource

An admission webhook, HPA, or another operator sets a field (replicas, annotations, resources) that is not in Git, so Argo CD sees a perpetual diff.

Argo CD diffs a server-populated field

Defaults the API server injects (for example a status block or a defaulted field) show as drift unless they are ignored or applied with server-side apply.

How to fix it

Ignore fields that other controllers own

  1. Run argocd app diff <app> to see exactly which field drifts.
  2. Add an ignoreDifferences entry for that field so Argo CD stops fighting the owning controller.
  3. Re-sync and confirm the app converges to Synced.
application.yaml
spec:
  ignoreDifferences:
    - group: apps
      kind: Deployment
      jsonPointers:
        - /spec/replicas

Use server-side apply for defaulted fields

ServerSideApply lets the API server own defaulted fields so they stop appearing as drift.

application.yaml
spec:
  syncPolicy:
    syncOptions:
      - ServerSideApply=true

How to prevent it

  • Use ignoreDifferences for fields owned by HPA, webhooks, or other controllers.
  • Prefer ServerSideApply so API-server defaults do not read as drift.
  • Run argocd app diff in CI to catch a perpetual diff before it blocks a wait.

Frequently asked questions

What causes Argo CD app stuck "OutOfSync" not converging in CI?
There are 2 common causes: a controller or webhook mutates the resource and argo cd diffs a server-populated field. An admission webhook, HPA, or another operator sets a field (replicas, annotations, resources) that is not in Git, so Argo CD sees a perpetual diff.
How do I fix Argo CD app stuck "OutOfSync" not converging in CI?
There are 2 fixes depending on which cause you have: ignore fields that other controllers own and use server-side apply for defaulted fields. Work through them in order, since the first is the most common.
What does Argo CD app stuck "OutOfSync" not converging in CI actually mean?
argocd app sync reports success but the Application immediately returns to OutOfSync, or a CI argocd app wait --sync never sees Synced and eventually times out.
How do I stop Argo CD app stuck "OutOfSync" not converging in CI happening again?
Use ignoreDifferences for fields owned by HPA, webhooks, or other controllers. The prevention section lists 3 changes that keep it from recurring.

Related guides

References

Not every red build is your code. Latchkey repairs the ones that are not, on the runner. Start free → 30-day trial · No credit card