# Fix terraform "Error: Saved plan is stale"

**TL;DR:** The state changed after you created the plan file, so the saved plan is no longer safe to apply. A plan records the state's lineage and serial; when `apply` sees the state has moved, it refuses. Re-run `terraform plan` to make a fresh plan against the current state, then apply that.

## The error

```text
Error: Saved plan is stale

The given plan file can no longer be applied because the state was changed by another operation after the plan was created.
```

## Steps

1. Find what moved the state: ask the team, check CI runs, or look at recent apply logs. Expected: you identify the apply that landed after your plan.
2. Re-run `terraform plan -out=tfplan`. Expected: the new plan is computed against the current state.
3. Review the fresh plan, then `terraform apply tfplan`. Expected: apply proceeds because lineage and serial match.
4. To stop it recurring, serialize plan and apply per workspace in CI so two pipelines cannot interleave. Expected: no more parallel-plan races.

## When this applies

- `terraform apply tfplan` fails with "Saved plan is stale" and the message about state changing after plan creation.
- Two PRs or pipelines planned against the same workspace and the first one applied first.

## When it does NOT apply

- Plan shows unexpected changes (drift). That is normal planning against current state, not a stale saved plan.
- You never saved a plan file. Plain `terraform apply` plans and applies in one go and cannot hit this.

## Tool and version compatibility

- All Terraform CLI versions. The lineage and serial check on saved plans has always been there.

## Why it happens

A saved plan is a promise: "apply exactly this, against exactly the state I saw." Terraform embeds the state's lineage and serial number in the plan file and verifies them at apply time. If any other operation wrote state in between, the promise is void and Terraform refuses rather than apply a plan computed against a world that no longer exists.

## Edge cases and pitfalls

- A plan file records nothing about your git commit. A plan made at commit A applies fine at commit B as long as the state never moved; review the code the plan was made from, not just the plan.
- Do not "fix" this with `-lock=false`. The staleness check is protecting you from a concurrent writer; disabling the lock makes the race worse.