Skip to main content
RunBook Academy

Git, CI/CD & GitOpsLXXXV · GitOps RollbackArgoCD

Argo CD rollback and history — `argocd app rollback`, `argocd app history`, and the rollback UI

Advanced⏱ ~22 mingit

What you'll learn

  • List the history of an Argo CD Application with `argocd app history`
  • Roll back an Argo CD Application with `argocd app rollback` and a specific history ID
  • Use the Argo CD UI rollback button and interpret its semantics
  • Combine the Argo CD rollback with a Git revert to close the rollback loop

Prerequisites

Verified against Git 2.55.x teaching target; 2.40+ minimum · GitHub Actions continuous service; Aug 2026 documentation baseline · Argo CD v3.5.x teaching target; v3.0+ minimum · Flux v2.9.x · Sigstore Cosign v3.1.x · SLSA v1.2 · OCI Distribution Specification v1.1 · Git LFS v3.7.1 · Kubernetes (cross-course target) 1.36.x

Not yet marked complete on this device.

Argo CD’s rollback is the controller-side half of a GitOps rollback. Every successful sync - whether automatic or manual, whether triggered by a webhook or by a CLI invocation - is recorded as an entry in the Application’s history. The history is the rollback surface: argocd app history lists the entries; argocd app rollback targets one. The UI exposes the same operation as a Rollback button in the Application’s history panel. The operations are additive: the Application object records the rollback as a new sync, the cluster’s resources converge to the targeted revision, and Git is unchanged.

The history model

An Argo CD Application tracks every sync the controller has performed. The history is a list of revisions, each with an identifier (a sequential ID), a source revision (the Git commit or Helm version that was applied), a deploy timestamp, and a status (Succeeded, Failed, or Running).

flowchart LR
    A["Application api"] --> H1["ID 4 - rev 8a3f9d2 - Succeeded"]
    A --> H2["ID 3 - rev 7c2e8b1 - Succeeded"]
    A --> H3["ID 2 - rev 5b1a0c3 - Succeeded"]
    A --> H4["ID 1 - rev 9d4e7f0 - Succeeded"]

Inspecting the history:

argocd app history $APP_NAME

Output is a table of revisions. Each row is one sync. The ID column is what argocd app rollback targets. The revision column is the Git commit (or the Helm version, or the OCI digest, depending on the source type) that the sync applied. The status column tells the operator which syncs are usable as rollback targets: only Succeeded entries are reliable rollback points.

The history window is configurable via the Application’s .spec.revisionHistoryLimit field. The default is 10; the field accepts any non-negative integer. A limit of 0 keeps only the most recent sync, which means argocd app rollback has nothing to revert to. The window must cover the rollback need the team commits to.

Rolling back via the CLI

argocd app rollback takes an Application name and an optional history ID. Without an ID, the command rolls back to the previous successful sync. With an ID, the command rolls back to that specific entry. The ID is a positional argument, not a flag.

argocd app rollback $APP_NAME
argocd app rollback $APP_NAME $HISTORY_ID

The first form is the common case: “roll back to the previous sync”. The second form is the precise case: “roll back to revision 7c2e8b1, which is the deploy we want to be on”. The ID is the number argocd app history prints in the ID column; it is a sequential integer, not a Git SHA.

One precondition: the rollback refuses to run while automated sync is enabled - the controller would otherwise re-sync to the branch tip and undo the rollback on the next tick. Disable automated sync first, and re-enable it only after Git has been reconciled with a revert:

argocd app set $APP_NAME --sync-policy none
argocd app rollback $APP_NAME $HISTORY_ID
# ... git revert lands on the branch ...
argocd app set $APP_NAME --sync-policy automated

The operation writes a new sync to the controller that targets the chosen revision. The controller re-applies the manifests at that revision to the cluster, the cluster’s resources converge, and the Application’s status moves to Synced once the rollout completes. The history records the rollback as a new entry with a new ID.

sequenceDiagram
    participant Op as Operator
    participant Argo as argocd CLI
    participant C as Application controller
    participant K as Cluster
    Op->>Argo: app set $APP_NAME --sync-policy none
    Op->>Argo: app rollback $APP_NAME 3
    Argo->>C: sync to revision 7c2e8b1
    C->>K: apply manifests at 7c2e8b1
    K-->>C: resources converged
    C-->>Argo: sync succeeded (new ID 5)
    Argo-->>Op: rollback complete

The rollback is recorded as a sync. With automated sync disabled for the duration, nothing re-syncs the Application on its own - but the branch still points at the bad commit. The next sync - triggered the moment automated sync is re-enabled, or by argocd app sync - will compare the cluster to the branch tip. If the branch tip is the same as the rolled-back-to revision, the diff is empty and the Application remains Synced. If the branch tip is the bad commit, the diff is non-empty and the controller will re-apply the bad manifests. The Argo CD rollback is therefore incomplete without a Git revert (or a new commit that supersedes the bad one); re-enable automated sync only after the revert has landed.

Rolling back via the UI

The Argo CD UI exposes the same operation. The Application detail page has a History panel; each entry has a menu with a Rollback option. Selecting Rollback on an entry prompts for confirmation and runs the same operation the CLI runs.

flowchart TB
    A["Application detail page"] --> B["History panel"]
    B --> C["Entry ID 3 (rev 7c2e8b1)"]
    C --> D["Rollback menu"]
    D --> E["Confirm"]
    E --> F["Sync to rev 7c2e8b1"]

The UI rollback is equivalent to argocd app rollback $APP_NAME $ID; it is the same controller call, with the same precondition that automated sync is disabled. The advantage of the UI is the visual identification of the target: the entry shows the revision, the timestamp, the deployer (when SSO is configured), and the source revision, which lets the operator verify the target before confirming. The CLI rollback requires the operator to know the ID and to trust that the ID maps to the revision they want.

What the rollback does and does not do

The Argo CD rollback restores the cluster’s resources to the manifests at the chosen history entry. It does not touch Git. It does not touch the container registry, the Helm chart repository, or any external state. It does not roll back the cluster’s data; rows in a database that were written under the bad revision remain after the rollback (see LXXXV-02).

flowchart LR
    A["argocd app rollback"] --> B["Cluster resources"]
    A -.-> X["Git branch - untouched"]
    A -.-> Y["Container registry - untouched"]
    A -.-> Z["Database rows - untouched"]

The boundaries the rollback does not cross define its reach. A team that uses the rollback as the only recovery step has restored one artifact while leaving three others drifted.

Common failure modes

Three failure modes are specific to the Argo CD rollback:

  • Rollback to a Failed entry. The history includes syncs that ended in Failed. Targeting a Failed entry re-applies manifests that did not converge the first time; the rollback will fail in the same way. The discipline is to verify the entry’s status before confirming the rollback.
  • Rollback past a destructive sync. A sync that included a Prune operation removed resources the previous sync had. Rolling back to a revision before the prune will re-create the pruned resources only if the manifests at that revision still declare them. If the manifests have moved on, the rollback is a partial reversion.
  • Stopping after the rollback, with the Git revert never committed. The rollback restores the cluster; auto-sync is off (as the rollback requires); the branch still points at the bad commit. The Application’s status is Synced but only because no one is asking the controller to reconcile. Re-enabling auto-sync, or running argocd app sync, will re-apply the bad manifests. The revert must land before auto-sync is re-enabled.

The combination: rollback plus Git revert

The complete rollback runs the Argo CD rollback and the Git revert. The order is: disable automated sync (the rollback refuses to run while it is enabled), the cluster rollback first (the cluster is the live system; restore the live system first), the Git revert second (the branch is the record; update the record after), and re-enable automated sync once the revert has landed.

argocd app set $APP_NAME --sync-policy none
argocd app rollback $APP_NAME
git revert $BAD_COMMIT
git push origin main
argocd app set $APP_NAME --sync-policy automated

The Argo CD rollback restores the cluster within seconds. The Git revert restores the branch; the pull request that wraps the revert preserves the review and CI discipline. Re-enabling automated sync before the revert lands would re-apply the bad manifests; re-enabling after, the next sync confirms the diff is empty. The Application is Synced; the branch is at a known-good commit; the audit trail records both operations.

Production discipline

  1. Configure .spec.revisionHistoryLimit to cover the rollback window the team commits to. A limit of 0 disables the rollback; a limit of 10 keeps the last ten syncs.
  2. Verify the entry’s status before rolling back. A Failed entry is not a usable rollback target.
  3. Disable automated sync before the rollback; re-enable it after the revert merges. The rollback refuses to run while automated sync is enabled, and re-enabling it before the branch is reverted re-applies the bad manifests.
  4. Wrap the Git revert in a pull request. The revert goes through the same review and CI discipline as any other change.
  5. Confirm the next sync has an empty diff. The rollback is complete only when the branch and the cluster agree.

Cross-course references

  • This course, Part LXXXV-01 (Git revert vs controller rollback) - the two halves of a rollback.
  • This course, Part LXXVII (Argo CD architecture) - the Application CRD that records the history.
  • This course, Part LIX-03 (Kubernetes rollback) - the Deployment-level rollback that the Argo CD rollback wraps.

Quiz

Knowledge check · 4 questions

  1. Q1. An on-call engineer disables automated sync and runs `argocd app rollback api` during an incident. The cluster restores to the previous sync; the Application is Synced. The engineer re-enables automated sync but does not commit a Git revert. What happens when the next webhook fires and the controller reconciles?

  2. Q2. Setting `.spec.revisionHistoryLimit: 0` on an Argo CD Application is a valid optimisation that reduces etcd storage by retaining only the most recent sync, with no operational consequences.

  3. Q3. Name the two Argo CD CLI commands that cover the rollback cases, and state what each does.

  4. Q4. Plan a rollback that combines the Argo CD CLI and a Git revert, and identify what to check in the Application's history before confirming the rollback.

    At 11:14 the team deploys a new release to production via a pull request merged into main. The PR is commit 8a3f9d2. At 11:22 a 5xx spike is observed; the diff shows the new release introduced a bad liveness probe path. The on-call engineer opens the Argo CD UI for the Application, sees history entries ID 4 (rev 8a3f9d2, Succeeded, 11:14), ID 3 (rev 7c2e8b1, Succeeded, 10:02), and ID 2 (rev 5b1a0c3, Failed, 09:48). The engineer needs to roll back.

Passing score: 75%. Answers are checked in this browser.