← All posts
Infra-as-Code

Terraform "Error acquiring the state lock"? Don't reflexively force-unlock

For developers and autonomous AI agents · ~5 min read

Your pipeline fails with Error acquiring the state lock: ConditionalCheckFailedException. The fastest-looking fix — terraform force-unlock or -lock=false — is also the one that can corrupt your state and orphan real infrastructure.

What the error means

Terraform takes a state lock before writing, so two runs can't modify state at once (which would corrupt it). The lock lives in the backend — a DynamoDB item for S3, a .tflock for GCS, a blob lease for Azure, a side-channel for Terraform Cloud. ConditionalCheckFailedException means the backend rejected your lock acquisition because a lock already exists. Someone — or something — holds it.

The trap: most of the time it's a stale lock from a crashed run or a killed CI job, so force-unlocking works. But you cannot tell a stale lock from a live apply by the error code alone — and force-unlocking a live apply lets two runs write state concurrently, which is exactly how state gets corrupted. The error code doesn't tell you which situation you're in.

The safe fix: read the Lock Info first

  1. Read the Lock Info block in the error — Who (who holds it), Created (how old), Operation. If Created is recent and you recognize Who, someone is actively running Terraform. Wait for them to finish — don't break their lock.
  2. Only if it's genuinely stale (a crashed process, a dead CI runner, no live run): back up the state file, then terraform force-unlock <LockID> using the ID from the error.
  3. If force-unlock fails (malformed lock, backend unreachable): delete the backend lock directly — DynamoDB delete-item on the LockID, gsutil rm the .tflock, or az storage blob lease break — but only after confirming no live apply.

Two things not to do

Snapback's iac-state family catches both the lock error and state drift — pass the error to diagnose_infra_error and it returns the check-Who/Created-before-force-unlock fix, so an agent doesn't blindly break a live lock.

For AI agents

Machine-readable guide: https://snapback.sh/llms.txt · Tool discovery: https://snapback.sh/.well-known/mcp.json · MCP endpoint: https://api.snapback.sh/mcp. Free tools need no token; pay-per-call diagnosis via x402 on Solana or EVM (~$0.0032 USDC).

Try Snapback freeRead the docs