An Argo CD Application shows OutOfSync but a sync fails or the diff looks wrong. Walk through how you'd troubleshoot it.
Quick Answer
Start with `argocd app diff` to see exactly what Argo CD believes differs between live and desired state, then check for common causes in order: a controller or admission webhook mutating fields after Argo CD applies them (causing perpetual drift), a Helm/Kustomize rendering difference between what's committed and what's actually generated, RBAC preventing Argo CD's service account from reading or applying specific resources, or a resource that's intentionally excluded/ignored via diff customizations that are misconfigured.
Detailed Answer
argocd app get <app> and argocd app diff <app> are the first stops — diff shows a live-vs-target manifest comparison so you can see exactly which fields Argo CD considers out of sync, rather than guessing from the UI's summary badge alone.
Common root causes, roughly in likelihood order for a persistent/confusing OutOfSync: (1) a mutating admission webhook or another controller (e.g. a HorizontalPodAutoscaler adjusting replica count, or a service mesh sidecar injector adding fields) modifies the resource after Argo CD applies it, and Argo CD's next reconciliation sees that as drift from Git — the fix is usually adding an ignoreDifferences rule for that specific field path in the Application spec, rather than fighting the other controller; (2) templating differences — what helm template or kustomize build renders locally doesn't exactly match what Argo CD renders server-side (different chart/kustomize version, different values precedence), which argocd app diff combined with running the same render command locally can confirm; (3) RBAC — the Argo CD Application controller's service account lacking permission on a specific resource type/namespace will cause sync failures on just those resources, visible in the Application's conditions/events rather than the diff itself; (4) resources explicitly excluded via syncOptions or the Application's ignoreDifferences block that were configured for a different reason and are now masking something real.
The systematic approach: reproduce the render locally (helm template/kustomize build) to rule out a templating mismatch first, since that's usually fastest to confirm or rule out, then check argocd app diff for the specific field-level differences, then check RBAC/events only if the diff shows a resource that never even got attempted.
Code Example
argocd app diff my-app argocd app get my-app -o wide helm template ./chart -f values.yaml # compare against what's actually rendered
Interview Tip
Naming 'another controller mutating fields after Argo CD applies them' as the top cause (versus assuming Argo CD itself is buggy) is the answer that signals real production troubleshooting experience.