Skip to main content
This guide covers best practices for upgrading Argo CD between versions, including breaking changes and migration procedures.

Versioning and Compatibility

Argo CD follows semantic versioning with these guarantees:

Patch Releases

v1.5.1 → v1.5.3No breaking changes or special instructions required. Safe to upgrade directly.

Minor Releases

v1.3.0 → v1.5.2May introduce changes with workarounds. Check upgrade notes for each minor version.

Major Releases

v2.14 → v3.0Introduces backward incompatible changes. Take backup and review migration guide carefully.
For major version upgrades, it is strongly recommended to take a backup using the disaster recovery guide before upgrading.

Standard Upgrade Procedure

Pre-Upgrade Checklist

1

Review release notes

Check the release notes for breaking changes and new features:
2

Backup Argo CD data

Create a backup of all Argo CD resources:
export VERSION=$(argocd version | grep server | awk '{print $2}')
docker run -v ~/.kube:/home/argocd/.kube --rm \
  quay.io/argoproj/argocd:$VERSION \
  argocd admin export > backup-$(date +%Y%m%d).yaml
3

Test in non-production

Always test upgrades in a development or staging environment first.
4

Check current version

argocd version

Upgrade Commands

For standard installations:
kubectl apply -n argocd --server-side --force-conflicts \
  -f https://raw.githubusercontent.com/argoproj/argo-cd/v3.4.0/manifests/install.yaml
The --server-side --force-conflicts flags are required because some Argo CD CRDs exceed the size limit for client-side apply operations.
Even for patch releases that only require image changes, it is recommended to apply the complete manifest set. Manifest changes might include important parameter modifications.

Post-Upgrade Verification

# Verify version
argocd version

# Check pod status
kubectl get pods -n argocd

# Verify applications are healthy
argocd app list

# Check for any stuck applications
argocd app list --output json | jq '.[] | select(.status.health.status != "Healthy")'

Major Version Upgrades

Upgrading to v3.0

Argo CD 3.0 introduces several important changes. Below are the most impactful breaking changes:
Change: Default resource tracking changed from labels to annotations.Detection:
kubectl get cm argocd-cm -n argocd -o jsonpath='{.data.application\.resourceTrackingMethod}'
# If empty or "label", you're using label-based tracking
Impact: Labels will be replaced with annotations on next sync. Applications won’t be marked as out-of-sync if labels are missing.Action Required:
  • Most users can upgrade safely
  • Applications with ApplyOutOfSyncOnly=true need manual sync after upgrade
  • Perform a sync operation on applications to apply annotations
Opt-out (if needed):
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-cm
  namespace: argocd
data:
  application.resourceTrackingMethod: label
Change: Policies granting update or delete no longer automatically apply to sub-resources.Impact: Users with applications, update permission can no longer automatically update/delete managed resources.Action Required: Update RBAC policies to explicitly grant sub-resource permissions:
# Old (v2.x) - implied sub-resource access
p, role:developer, applications, update, myproject/*, allow

# New (v3.0) - explicit sub-resource access required
p, role:developer, applications, update, myproject/*, allow
p, role:developer, applications, update/*, myproject/*, allow
Restore v2 behavior:
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-cm
  namespace: argocd
data:
  server.rbac.disableApplicationFineGrainedRBACInheritance: "false"
Change: Logs RBAC is now enforced by default (previously optional).Detection:
# Check if already enforced
kubectl get cm argocd-cm -n argocd -o jsonpath='{.data.server\.rbac\.log\.enforce\.enable}'
Impact: Users need explicit logs, get permission to view pod logs in UI.Quick fix (global access):
# In argocd-rbac-cm ConfigMap
policy.csv: |
  p, role:readonly, logs, get, */*, allow
  g, <user>, role:readonly
Recommended fix (per-policy):
policy.csv: |
  p, role:developer, applications, get, myproject/*, allow
  p, role:developer, logs, get, myproject/*, allow
Change: High-volume Kubernetes resources are now excluded by default.Excluded resources:
  • Kubernetes: Endpoints, EndpointSlice, Lease, TokenReview, CertificateSigningRequest
  • Cert Manager: CertificateRequest
  • Kyverno: EphemeralReport, AdmissionReport, BackgroundScanReport
  • Cilium: CiliumIdentity, CiliumEndpoint
Impact: Reduces API load on large clusters, improves performance.Override (if needed):
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-cm
  namespace: argocd
data:
  resource.exclusions: |
    # Override with your custom exclusions
    - apiGroups:
      - ""
      kinds:
      - Endpoints
      clusters:
      - "*"
Change: Helm upgraded to 3.17.1 with stricter null handling.Issue: values.yaml files with null object values will override subcharts.Example problem:
# This will now override the subchart value
postgresql:
  enabled: null  # ❌ Will cause issues
Solution: Remove null values:
# Comment out or remove instead
postgresql:
  enabled: false  # ✅ Use explicit false
Change: RBAC subject now uses federated_claims.user_id instead of sub claim.Detection: If using Dex SSO, check existing RBAC policies.Action Required: Decode existing sub claims and update policies:
# Decode sub claim to get user_id
echo "ChdleGFtcGxlQGFyZ29wcm9qLmlvEgJkZXhfY29ubl9pZA" | base64 -d
# Output: example@argoproj.io
Update RBAC policies:
# Old (incorrect)
- g, ChdleGFtcGxlQGFyZ29wcm9qLmlvEgJkZXhfY29ubl9pZA, role:admin

# New (correct)
- g, example@argoproj.io, role:admin

Upgrading to v3.4

Change: Applications now show Missing health only when ALL resources are missing.New behavior:
  • Individual missing resources don’t affect overall health
  • Health reflects existing resources (Healthy, Progressing, Degraded)
  • Use OutOfSync status to detect missing resources
Impact: Automation relying on Missing health status should check OutOfSync instead.
# Old way - check health for missing resources
argocd app list --health-status Missing

# New way - check sync status
argocd app list --sync-status OutOfSync
Change: gRPC service config DNS lookups disabled by default.Reason: Prevents excessive DNS queries in dual-stack (IPv4+IPv6) environments.Impact: Minimal for most users. Only affects those using DNS TXT records for gRPC config.Re-enable (if needed):
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-cmd-params-cm
  namespace: argocd
data:
  controller.grpc.enable.txt.service.config: "true"
Changes:
  • Gomplate now used internally
  • ContinueOnConnectorFailure enabled by default
Disable if needed:
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-cmd-params-cm
  namespace: argocd
data:
  dexserver.connector.failure.continue: "false"

Upgrade Strategies

Rolling Upgrade (Zero Downtime)

For production environments:
1

Scale API server

Ensure multiple replicas before upgrade:
kubectl scale deployment argocd-server -n argocd --replicas=3
2

Apply manifests

kubectl apply -n argocd --server-side --force-conflicts \
  -f https://raw.githubusercontent.com/argoproj/argo-cd/v3.4.0/manifests/ha/install.yaml
3

Monitor rollout

kubectl rollout status deployment argocd-server -n argocd
kubectl rollout status deployment argocd-repo-server -n argocd
kubectl rollout status statefulset argocd-application-controller -n argocd

Blue-Green Upgrade

For critical environments:
  1. Deploy new Argo CD instance: Install new version in parallel namespace
  2. Import configuration: Restore from backup to new instance
  3. Validate functionality: Test applications in new instance
  4. Switch traffic: Update ingress/LoadBalancer to new instance
  5. Decommission old instance: After validation period

Rollback Procedure

If issues occur after upgrade:
# Rollback to previous version
kubectl apply -n argocd --server-side --force-conflicts \
  -f https://raw.githubusercontent.com/argoproj/argo-cd/v2.14.0/manifests/install.yaml

# Or restore from backup
docker run -i -v ~/.kube:/home/argocd/.kube --rm \
  quay.io/argoproj/argocd:v2.14.0 \
  argocd admin import - < backup-20260301.yaml

Version-Specific Upgrade Guides

v3.3 to v3.4

Latest minor version upgrade

v3.0 to v3.1

Minor version with new features

v2.14 to v3.0

Major version upgrade guide

Best Practices

Backup First

Always create a backup before major version upgrades using argocd admin export.

Test Upgrades

Test upgrade procedures in non-production environments before applying to production.

Read Release Notes

Carefully review release notes for breaking changes and required actions.

Monitor After Upgrade

Watch metrics and logs closely after upgrade to catch issues early.

Staged Rollout

Upgrade development → staging → production in stages with validation between.

Maintain Version Parity

Keep CLI version matched with server version to avoid compatibility issues.