Argo CD "argocd app diff" exits nonzero on drift in CI
argocd app diff returns exit code 1 when there is any difference between the desired manifests and live state. In a CI drift-check, that nonzero exit is the signal, but it can also fail a pipeline unexpectedly if you did not intend it as a gate.
What this error means
A pipeline step running argocd app diff fails with exit code 1 and prints a unified diff, even though no command "errored" in the usual sense.
===== apps/Deployment prod/api ======
5c5
< replicas: 3
---
> replicas: 2
Error: Process completed with exit code 1.Common causes
Live state differs from Git
The diff found a real difference (a manual change, a controller mutation, or a pending sync), so it exits 1 by design.
A field the cluster owns shows as drift
Server-defaulted or controller-owned fields appear in the diff unless ignored, producing a nonzero exit on every run.
How to fix it
Decide whether the diff should gate
- If drift detection is intended, treat exit 1 as expected and report it, do not fail hard.
- If it is an unintended gate, sync first so the diff is empty, then run the check.
- Ignore fields owned by controllers so they do not read as drift.
argocd app diff my-app || echo "drift detected"Ignore controller-owned fields
Add ignoreDifferences for fields other controllers set so the diff reflects only real drift.
spec:
ignoreDifferences:
- group: apps
kind: Deployment
jsonPointers:
- /spec/replicasHow to prevent it
- Decide explicitly whether
app diffis a gate or a report. - Use ignoreDifferences so controller-owned fields do not show as drift.
- Sync before diffing when you expect no difference.