Skip to content
Latchkey

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.

terraform
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:02

Common 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

  1. Use a CI concurrency group so only one plan/apply touches a given state at a time.
  2. Wait for the in-flight run to finish -- a genuine concurrent lock clears on its own.
  3. Avoid running plan and apply for the same workspace in parallel.
.github/workflows/terraform.yml
concurrency:
  group: terraform-${{ github.workflow }}-prod
  cancel-in-progress: false

Force-unlock only a confirmed stale lock

After confirming no run is active, remove the stale lock by its ID from the error.

Terminal
terraform force-unlock 9b1f...-state

How 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.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →