Terraform "Error acquiring the state lock" in CI
Terraform uses a lock so two runs cannot mutate the same state at once. Acquisition failed because another run currently holds the lock, or a previous run crashed and left a stale lock behind in the backend (DynamoDB, GCS, etc.).
What this error means
plan/apply aborts with Error acquiring the state lock and a Lock Info block (ID, Who, Created, Operation). A concurrent run is transient and clears when it finishes; a stale lock from a crashed run persists until it is removed.
Error: Error acquiring the state lock
Error message: ConditionalCheckFailedException: The conditional request failed
Lock Info:
ID: 9b1f...-state
Who: runner@ci
Operation: OperationTypeApply
Created: 2026-06-26 10:14:02Common causes
Another run holds the lock
A concurrent plan/apply (a parallel CI job, a teammate, a scheduled run) currently owns the lock; the second run cannot proceed until the first releases it.
Stale lock from a crashed run
A run that was killed (timeout, cancelled job, lost runner) never released the lock, so the backend still records it as held even though no process is running.
How to fix it
Serialize runs against the same state
- Use a CI concurrency group so only one plan/apply touches a given state at a time.
- Wait for the in-flight run to finish -- a genuine concurrent lock clears on its own.
- Avoid running plan and apply for the same workspace in parallel.
concurrency:
group: terraform-${{ github.workflow }}-prod
cancel-in-progress: falseForce-unlock only a confirmed stale lock
After confirming no run is active, remove the stale lock by its ID from the error.
terraform force-unlock 9b1f...-stateHow to prevent it
- Gate Terraform jobs behind a CI concurrency group per state/workspace.
- Set sensible timeouts so crashed runs are noticed quickly.
- On Latchkey, self-healing managed runners auto-retry the transient lock-contention case so a run that loses the race to a concurrent job retries once the lock is released, rather than failing outright.