ArgoCD app stuck in OutOfSync: how to force refresh
Resolves ArgoCD applications stuck in OutOfSync. Use when syncs do not clear the state, when the diff shows phantom changes, or when you need a clean resync. Covers refresh, diff causes, and safe force options. Not for apps that fail to deploy.
TL;DR
OutOfSync that will not clear is usually a stale cache, a diff the app will never converge on (like a field the cluster mutates), or a sync that partially applied. Refresh the app to bust the cache first, read the actual diff second, and only then reach for force sync or ignore-differences. Most stuck states clear at step one or two.
The query
ArgoCD app stuck in OutOfSync: how to force refreshUse this when
- An app shows OutOfSync persistently
- Syncs complete but the state does not change
- The diff shows changes you did not make
- You need the app to match git cleanly
Not for when
- Apps failing to deploy at all (different problem)
- Sync errors and hook failures
- First-time app setup
Steps
Step 1: Trigger a hard refresh
Refresh the app with the hard refresh option to bypass ArgoCD's cache and recompute state from the cluster and git directly. Cached state is the most common cause of phantom OutOfSync. Expected output: the app either shows Synced (it was a stale cache) or the diff is now accurate.
Step 2: Read the actual diff
Look at what differs between git and the cluster, resource by resource. The usual suspects: fields the API server defaults or mutates (replicas on HPA-managed deployments, cluster-assigned IPs), or out-of-band changes someone applied with kubectl. Expected output: the specific fields and resources that differ, named explicitly.
Step 3: Handle mutating fields with ignoreDifferences
For fields the cluster legitimately manages (things controllers rewrite), add ignoreDifferences rules to the app config. Fighting the cluster on these fields means permanent OutOfSync; ignoring them is the correct fix. Expected output: the diff shrinks to real differences only.
Step 4: Sync with prune and the right options
Run a sync, enabling prune only if you intend to delete out-of-band resources. For a stuck app, a sync with replace can help when the diff involves immutable fields that a normal apply cannot update. Expected output: the app converges to Synced, or the sync error names the blocking resource.
Step 5: Force sync as the last resort
If the app is still stuck and you understand the diff, use force sync to overwrite. Reserve this for when you are certain git is the source of truth and the cluster state is wrong or corrupted. Expected output: the cluster matches git; the app shows Synced. Document why force was needed.
Provenance
Resolved from the public thread: https://vectle.com/posts/pstROOTloBUxoB0uWaUPAokw
Maintainer review
No maintainer verification is recorded for this version.
This records the version a maintainer checked. It does not assert that the version is the latest upstream release.