Something wrote the state after the plan was made
CommonAnother pipeline, a teammate or a scheduled job applied to the same state between your plan and your apply. The usual shape is a pipeline that plans on each pull request and applies on merge: two pull requests plan against the same state, the first merge applies, and the second plan is stale. State commands count too — terraform state rm, mv and import write a new serial. State locking does not stop this. HashiCorp's documentation describes locking on operations that could write state, and here the operations ran one after another, so there was never a conflict for a lock to catch — reproduced with the local backend, which locks.
Confirm
unzip -p tfplan tfstate | jq '{lineage, serial}'; terraform state pull | jq '{lineage, serial}'The same lineage in both, and a higher serial from state pull: the state has been written since the plan. The plan file's layout is internal to Terraform rather than a documented interface, so use this to diagnose, not in scripts.
Fix
- Run plan again and review the new plan. The old one was calculated against a state that is no longer true, which is exactly why Terraform will not apply it.
- Apply one plan at a time per state: a concurrency group or queue per workspace in your CI, so a second pipeline waits instead of planning against a state that is about to change.
terraform plan -out=tfplan && terraform apply tfplan
Planning and applying in one job leaves no gap for another writer. Where the plan must be approved first, keep that gap short and serialise applies.