Terraform: Error Acquiring the State Lock — How to Fix It
Error: Error acquiring the state lock
Error message: ConditionalCheckFailedException: The conditional request failed
Lock Info:
ID: a1b2c3d4-e5f6-7890-abcd-ef1234567890
Path: s3://my-bucket/terraform.tfstate
Operation: OperationTypeApply
Who: user@hostname
Version: 1.6.0
Created: 2024-01-15 10:30:00.000000 +0000 UTC
This error means another Terraform process holds the state lock, or a previous run crashed and left a stale lock behind. Terraform uses locking to prevent two people from modifying infrastructure at the same time.
What causes this
Terraform acquires a lock on the state file before any operation that modifies state (plan, apply, destroy). The lock is stored in your backend — typically a DynamoDB table for S3 backends, or a lease for Consul/Azure backends.
You’ll see this when:
- A teammate is running
terraform applyon the same state - A previous run was interrupted (Ctrl+C, CI timeout, network drop) and didn’t release the lock
- A CI/CD pipeline crashed mid-apply
- You have two terminals running Terraform against the same workspace
Fix 1: Wait for the other process
Check the lock info in the error message. The Who field tells you who holds the lock. If it’s a teammate, wait for them to finish. If it’s a CI pipeline, check if it’s still running.
# The error message shows who holds the lock
# Who: jane@dev-machine
# Created: 2024-01-15 10:30:00
Fix 2: Force unlock the state
If the process that held the lock has crashed or been killed, the lock is stale. Use the lock ID from the error message:
terraform force-unlock a1b2c3d4-e5f6-7890-abcd-ef1234567890
Terraform will ask for confirmation. Only do this when you’re sure no other process is actively running. Force-unlocking while another apply is in progress can corrupt your state.
Fix 3: Check for zombie processes
If the lock holder is your own machine, you might have a zombie Terraform process:
# Find running Terraform processes
ps aux | grep terraform
# Kill the stuck process
kill <PID>
# Then unlock if needed
terraform force-unlock LOCK_ID
Fix 4: Check the DynamoDB lock table directly
For S3 backends, the lock is stored in DynamoDB. You can inspect it directly:
aws dynamodb scan --table-name terraform-locks
If you see a stale lock entry and force-unlock isn’t working, you can delete it manually — but this is a last resort:
aws dynamodb delete-item \
--table-name terraform-locks \
--key '{"LockID": {"S": "my-bucket/terraform.tfstate"}}'
How to prevent it
- Use CI/CD for all Terraform operations instead of running from local machines. This eliminates the “two people running at once” problem.
- Configure CI timeouts with cleanup steps that run
terraform force-unlockif the job is cancelled. - If you must run locally, communicate with your team before running
applyon shared state. - Consider using Terraform Cloud or Spacelift, which handle locking and queueing automatically.