## TL;DR
`kubectl rollout undo` rolls a deployment back to its previous ReplicaSet in one command, and it is safe because the old ReplicaSet is still there. Check the revision history first, undo (optionally to a specific revision), then watch the rollout and verify the app actually recovered. Keep `revisionHistoryLimit` above 2 or there will be nothing to roll back to.

## Error / query
```text
kubectl rollout undo: safe rollback steps
```

## Use this skill when
- A new deploy broke the app and you need the old version back fast
- A rollout is stuck and backing out is safer than pushing forward
- You want to see what revision you would roll back to before doing it
- Validating that rollbacks actually work before you need one

## Not for this skill when
- ArgoCD/Flux manages the deploy (roll back in git, not with kubectl)
- The bad change includes a database migration (rollback needs a data plan)
- You want to roll forward with a fix instead (often the better call)

## Steps

### Step 1: Check what revisions exist
```bash
kubectl rollout history deployment/[deployment] -n [namespace]
```
Expected: a numbered list of revisions with change causes. You need at least revision N-1 present; if history shows only the current revision, `revisionHistoryLimit` was too low and undo has nothing to restore.

### Step 2: Preview the revision you would restore
```bash
kubectl rollout history deployment/[deployment] -n [namespace] --revision=[N-1]
```
Expected: the pod template of that revision (image, env, args). Confirm it is the known-good version before undoing; rolling back to another bad revision just wastes time.

### Step 3: Undo the rollout
```bash
kubectl rollout undo deployment/[deployment] -n [namespace]
# or to a specific revision:
# kubectl rollout undo deployment/[deployment] -n [namespace] --to-revision=[N-1]
```
Expected: the deployment starts scaling up the old ReplicaSet and scaling down the new one. This is a normal rolling update in reverse, so readiness probes still gate traffic.

### Step 4: Watch and verify recovery
```bash
kubectl rollout status deployment/[deployment] -n [namespace] --timeout=10m
kubectl get pods -n [namespace] -l app=[app]
```
Expected: rollout completes and pods are Running and Ready on the old image. Then verify the app symptom is actually gone (hit the health endpoint, check error rates); a completed rollout on the wrong revision is not a recovery.

## Variant phrasings

### "kubectl rollback deployment"
`kubectl rollout undo` is the command; `rollback` is not a kubectl verb.

### "how to undo a kubernetes deployment"
Steps 1-4. Check history first so you know the target revision exists.

## Why it happens
Deployments keep old ReplicaSets around (up to `revisionHistoryLimit`, default 10) precisely so a bad rollout can be reversed without rebuilding anything. Undo just changes which ReplicaSet is scaled up; no new images are pulled and no manifests are edited, which makes it the fastest recovery path for a bad deploy.

## Edge cases and pitfalls
- Undo does not reverse database migrations or external state changes; rolling back code against a migrated schema can break worse.
- If the bad deploy changed the deployment's selector or labels, undo may not match old pods cleanly; check the revision diff first.
- HPA can fight a rollback by scaling the new ReplicaSet during the transition; consider pausing or scaling HPA first for big rollbacks.
- In GitOps setups, undo is temporary: the next sync re-applies the git state. Revert the git commit to make the rollback stick.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_pHmjC7jnlbeuDgP52VmsaQ
