How to Perform Rollbacks with Argo CD: CLI, API, and Source Code Deep Dive
Argo CD treats rollbacks as a convenient wrapper around the standard sync operation that targets a specific revision history entry by its numeric ID, delegating to the same sync engine used for forward deployments.
Performing rollbacks with Argo CD is a critical operational capability for the argoproj/argo-cd project. Unlike specialized rollback mechanisms in other GitOps tools, Argo CD implements rollbacks as a specialized invocation of its standard sync logic. This design ensures that rollbacks benefit from identical safety features, RBAC enforcement, and validation as regular deployments.
Understanding the Rollback Architecture
The Sync Wrapper Pattern
According to the source code in server/application/application.go, a rollback is fundamentally a convenience wrapper around the normal sync operation. When you trigger a rollback, the controller constructs an ApplicationRollbackRequest that points to a previous revision history entry, then executes a standard sync using that historical state as the target.
This architectural decision means rollbacks inherit all sync features: resource pruning, dry-run validation, hook execution, and fine-grained RBAC checks. The actual implementation in server/application/application.go (starting at line 2266) delegates immediately to the generic sync logic:
// server/application/application.go – Rollback handler
func (s *Server) Rollback(ctx context.Context, rollbackReq *application.ApplicationRollbackRequest) (*v1alpha1.Application, error) {
// … validation omitted …
// Rollback is just a convenience around Sync
return s.syncApp(ctx, &application.ApplicationSyncRequest{
Name: rollbackReq.Name,
Id: rollbackReq.Id,
DryRun: rollbackReq.DryRun,
Prune: rollbackReq.Prune,
SyncOptions: []string{}, // populated from history entry
SourceOverrides: rollbackReq.SourceOverrides,
})
}
The ApplicationRollbackRequest Structure
The rollback request structure is defined in pkg/apiclient/application/application.pb.go (around line 1300) and carries the essential parameters for the operation:
- Name: The target application name
- Id: The numeric history ID to roll back to (optional; defaults to previous successful revision)
- Prune: Boolean to remove resources not present in the target revision
- DryRun: Boolean to preview changes without applying them
- SourceOverrides: Optional parameter overrides for the sync operation
Performing Rollbacks via the CLI
The argocd app rollback command provides the most common interface for performing rollbacks. If you omit the history ID, Argo CD automatically selects the previous successful revision.
# Roll back "my-app" to the previous successful revision
argocd app rollback my-app
# Roll back to a specific history entry (ID = 3) with pruning and dry-run preview
argocd app rollback my-app 3 --prune --dry-run
# Rollback with project specification
argocd app rollback my-app 5 --project my-project
The CLI translates these commands into gRPC calls to the Rollback RPC endpoint, passing the appropriate ApplicationRollbackRequest parameters.
Implementing Rollbacks via the API
For programmatic control, you can invoke rollbacks directly through the gRPC API using the Go client. This approach is essential for building custom automation or integrating rollback capabilities into internal tooling.
import (
"context"
"github.com/argoproj/argo-cd/pkg/apiclient/application"
v1alpha1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
)
func rollbackApp(client application.ApplicationServiceClient, appName string, historyID int64) (*v1alpha1.Application, error) {
req := &application.ApplicationRollbackRequest{
Name: &appName,
Id: &historyID,
Prune: true,
DryRun: false,
}
return client.Rollback(context.Background(), req)
}
The API supports the same flags as the CLI, including --dry-run, --prune, and --revision overrides, allowing you to validate rollback operations before applying them to the cluster.
Internal Server Implementation
The core rollback handler resides in server/application/application.go at line 2266. The Server.Rollback method performs minimal validation before delegating to s.syncApp, which resolves the historic manifest from the application's revision history stored in the controller.
Because the sync engine resolves the target state from the revision history cache rather than live Git repository polling, rollbacks are fast and deterministic. The engine applies the historic manifest to the cluster, optionally pruning resources that disappeared in the target revision, then updates the application's status. The UI's "Rollback" button performs the same API call behind the scenes, creating a new history entry once the operation completes.
Testing and Validation
The Argo CD codebase includes comprehensive tests verifying rollback behavior:
- End-to-end tests in
test/e2e/app_management_test.go(line 563) verify rollback functionality in live clusters - Unit tests in
server/application/application_test.go(line 1003) exercise the rollback API with various edge cases and permission scenarios - CLI documentation in
docs/user-guide/commands/argocd_app_rollback.mdprovides the complete command-line reference
Summary
- Argo CD rollbacks are sync operations that target specific revision history entries by numeric ID, leveraging the standard sync engine for consistency and safety.
- The
ApplicationRollbackRequeststructure inpkg/apiclient/application/application.pb.godefines the API contract, supporting dry-run, pruning, and source overrides. - The CLI command
argocd app rollbackautomatically selects the previous successful revision if no ID is specified, or targets a specific history entry when provided. - Server implementation in
server/application/application.go(line 2266) delegates to the generic sync logic, ensuring rollbacks inherit RBAC, validation, and hook execution. - Omitting the history ID triggers an automatic rollback to the most recent successful deployment, providing a convenient "undo last change" capability.
Frequently Asked Questions
What happens if I don't specify a history ID when performing a rollback?
If you omit the history ID, Argo CD automatically rolls back to the previous successful revision in the application's history. This provides a convenient "undo" mechanism for recent changes without requiring you to look up specific revision numbers.
Is a rollback safer than a regular sync operation?
No, and yes. Because rollbacks use the exact same sync engine as forward deployments, they carry identical safety characteristics and risks. However, they benefit from the same protections: dry-run validation, resource pruning controls, and comprehensive RBAC enforcement. The key difference is that rollbacks target a known, previously-deployed state rather than a potentially untested new commit.
Can I rollback to any arbitrary commit in the Git repository?
No. Argo CD rollbacks can only target revisions that exist in the application's revision history—states that have been previously synced and recorded by the controller. You cannot rollback to an arbitrary Git commit that was never deployed through Argo CD. To deploy an arbitrary commit, use a standard sync with a specific revision override instead.
How does rollback handle resource pruning?
When you specify the --prune flag (or set Prune: true in the API), the rollback operation removes resources that exist in the current cluster state but are absent from the target historical revision. This ensures the cluster state matches the historical desired state exactly, preventing orphaned resources from accumulating during rollbacks.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →