Infra Notes

Terraform error acquiring the state lock: recover without state damage

Resolve Terraform state lock errors by identifying active runs, verifying the backend and workspace, waiting safely, and using force-unlock only as a last resort.

Published

TerraformTerraform State LockError Acquiring State Lockforce-unlockRemote StateTerragrunt

Problem

Terraform reports Error acquiring the state lock. The lock protects a state snapshot from concurrent writers. Removing it without proving that the owner has stopped can allow two applies to modify the same state and infrastructure concurrently.

Quick answer

  1. Record the lock ID, operation, owner, timestamp, and state path from the error.
  2. Check CI, HCP Terraform, and operator sessions for an active plan, apply, import, or state command.
  3. Confirm your backend configuration and selected workspace.
  4. If another run is active, wait or cancel it through its owning system.
  5. Use terraform force-unlock only after proving the lock is stale.

For short contention, prefer waiting:

bash

terraform plan -lock-timeout=5m

This preserves serialization instead of bypassing locking with -lock=false.

Confirm the state target

Before changing a lock, verify that the working directory points to the expected backend and workspace:

bash

terraform workspace show
terraform version
terraform init -reconfigure

With Terragrunt, also verify the environment path and rendered remote-state key. Similar repository directories can intentionally use different state objects.

Do not run init -migrate-state casually during incident diagnosis; migration changes where state is stored and requires its own reviewed procedure.

Determine whether the lock is stale

A lock may remain after an interrupted local process, terminated CI runner, lost network connection, or failed backend request. It is stale only when the recorded owner no longer has a process capable of writing that state.

Check:

  • The workflow run referenced by the lock owner
  • Other infrastructure pipelines for the same environment
  • HCP Terraform run status when applicable
  • Operator processes and change windows
  • Backend health and access permissions

If the owning run still exists, cancel or complete it there. Do not unlock underneath it.

Last resort: force-unlock

After confirming the lock is stale, use the exact lock ID:

bash

terraform force-unlock <LOCK_ID>

Avoid -force in interactive operations because the confirmation is a useful final guardrail. The command removes the lock for the current configuration; it does not repair a wrong backend, reconcile a partially completed cloud operation, or validate state consistency.

After unlocking, run a normal refresh-backed plan and review unexpected changes before applying:

bash

terraform plan

Avoid these dangerous responses

  • -lock=false does not fix contention; it disables the protection.
  • Do not delete backend lock records manually when the Terraform command can handle them.
  • Do not edit terraform.tfstate directly.
  • Do not push state merely because a plan looks different after an interrupted run.

Centralize applies, serialize them per state object, cancel pipelines cleanly, and use short-lived cloud identities. The broader design is described in the Infrastructure as Code platform blueprint.

References