Self-managed Argo CD upgrades¶
Argo CD reconciles the platform — including itself. The controller's own Application lives in the same app-of-apps it manages, which makes upgrading it a small chicken-and-egg exercise: the thing applying the change is the thing being changed.
Why the self-app is not auto-synced¶
Every other Application can auto-sync safely. The Argo CD self-Application deliberately does not — auto-applying a bad bump to the controller could break the very component you'd use to roll it back. So its sync is manual: the new version sits in Git, visibly OutOfSync, until a human applies it.
The upgrade¶
- Land the version bump in Git (chart/image), reviewed like any change. The self-Application goes OutOfSync; nothing happens yet.
- Apply CRDs first if the release changes them. Argo CD's CRDs can be too large for a client-side apply and can lag a normal sync — apply/upgrade them with server-side apply before syncing the app, so the controller doesn't come up expecting schema that isn't there.
- Manually sync the self-Application. Argo CD applies its own new manifests and its pods roll. Expect the UI/API to blink during the rollout.
- Confirm it came back and is reconciling. Once the new controller is Healthy, check that it still syncs the other Applications — that's the real success test, not just its own pods being Ready.
What keeps this safe¶
- A brief Argo CD outage is not a workload outage. While the controller restarts, everything it already deployed keeps running — pods, Services, and ingress are unaffected. You're only without reconciliation for a minute, not without the platform.
- Per-layer isolation. Each layer has its own Argo CD, so this dance is done one instance at a time and a mistake is contained to that layer. See Architecture.
If a sync wedges on an immutable field
Some in-place updates are forbidden by Kubernetes (for example changing a StatefulSet's volume
claim template). The sync will fail with a Forbidden error and retry forever. Recreate the
object without deleting its pods — an orphan delete (--cascade=orphan) removes the object
but leaves the running pods and volumes — and let Argo CD recreate it from Git. Do this only
after the app's target already points at the new revision, or self-heal will just recreate the
old spec.
See also: Upgrade methodology · Common operations.