State Locking
Whenever Terraform is about to read or write state, it first attempts to acquire a lock. If another operation already holds that lock — say, a teammate mid-apply on the same configuration — Terraform blocks and reports that the state is locked, rather than proceeding and risking two processes overwriting each other's changes. This matters because state operations are not atomic merges: if two applies ran concurrently against the same state file without coordination, the second write would simply clobber the first, silently dropping resource records and leaving Terraform's understanding of infrastructure out of sync with reality.
Cricket analogy: Before a bowler can change the ball mid-over, the umpire must sign off; if the umpire is already mid-review on another decision, the request waits rather than risking two rulings on the same delivery colliding.
How Locking Is Implemented Per Backend
Locking support and mechanism vary by backend. The S3 backend historically paired with a DynamoDB table to hold lock records (one item per state file, keyed by a LockID attribute), though newer versions of Terraform support native S3 locking via conditional writes without a separate table. Azure's backend uses blob leases on the state blob itself, and Terraform Cloud/Enterprise manages locking centrally as part of its run orchestration. Not all backends support locking — the plain local backend uses a local .tfstate.lock.info file, which only protects against concurrent processes on the same machine, not across a team.
Cricket analogy: Different grounds use different security protocols: a major stadium like the MCG uses biometric badge locks at every gate, while a small local ground might just have one guard at a single entrance who only stops one person at a time.
Handling a Stuck Lock
Locks are normally released automatically when an operation finishes or is cancelled cleanly. But a crashed process, a killed CI job, or a network interruption can leave a stale lock behind, blocking all future operations. Terraform provides terraform force-unlock <LOCK_ID> for exactly this situation — but it is a manual override that bypasses the safety mechanism, so it should only be used after confirming no other operation is genuinely still running against that state.
Cricket analogy: If a curator falls ill mid-pitch-prep and never signals the ground is ready, officials can override the hold and declare the ground open manually, but only after confirming no other prep work is genuinely still underway.
$ terraform apply
Error: Error acquiring the state lock
Error message: ConditionalCheckFailedException: The conditional request failed
Lock Info:
ID: 7d9f2a31-52c8-4e9b-9c0a-1b6e4d8f3a22
Path: acme-terraform-state/platform/networking/terraform.tfstate
Operation: OperationTypeApply
Who: ci-runner-04@build-agent
Version: 1.9.2
Created: 2026-07-09 14:02:11 UTC
$ terraform force-unlock 7d9f2a31-52c8-4e9b-9c0a-1b6e4d8f3a22
Do you really want to force-unlock?
Terraform will remove the lock on the remote state.
This will allow local Terraform commands to modify this state, even though it
may still be in use. Only 'yes' will be accepted to confirm.
Enter a value: yes
Terraform state has been successfully unlocked!State locking works like a library book checkout system: whoever has the book (the lock) can read and annotate it, but everyone else must wait until it's returned before they can check it out, preventing two people from scribbling conflicting notes in the same margin simultaneously.
Force-unlocking when another operation is genuinely still in progress can lead to exactly the corruption locking was meant to prevent — two writers proceeding at once. Always verify with your team or CI system that the holder of the lock has actually crashed or stalled before running force-unlock.
- State locking prevents concurrent Terraform operations from writing to the same state file at once.
- Without locking, concurrent applies can silently overwrite each other's changes, corrupting the recorded infrastructure.
- Lock implementation is backend-specific: DynamoDB or native S3 conditional writes, Azure blob leases, or centralized locking in Terraform Cloud.
- The local backend only locks against concurrent processes on the same machine, not across a team.
- terraform force-unlock manually clears a stuck lock but bypasses the safety mechanism and must be used cautiously.
- Always confirm the lock holder has actually crashed before forcing an unlock, to avoid re-introducing a race condition.
Practice what you learned
1. What is the primary purpose of Terraform state locking?
2. Historically, what did the S3 backend commonly pair with to implement locking?
3. What command manually clears a lock that was left behind by a crashed process?
4. What is a key limitation of locking with the plain local backend?
5. What risk does force-unlocking a state file carry if the original operation is actually still running?
Was this page helpful?
You May Also Like
Remote State Backends
Remote backends store Terraform's state file outside the local disk, enabling team collaboration, durability, and integration with locking mechanisms.
The Terraform State File
Terraform's state file is the source of truth mapping your configuration to real-world resources. Understanding its structure and risks is essential for safe, collaborative infrastructure management.
Terraform in CI/CD Pipelines
Learn the standard stages, safety controls, and credential-handling patterns for running Terraform reliably inside a CI/CD pipeline, from plan-on-PR to gated apply-on-merge.
Drift Detection
Understand configuration drift — when real infrastructure diverges from Terraform state — and the tools and practices used to detect and reconcile it before it causes surprises.
Related Reading
Related Study Notes in DevOps
Browse all study notesNginx Study Notes
DevOps · 30 topics
DevOpsAnsible Study Notes
DevOps · 30 topics
DevOpsAdvanced Kubernetes Study Notes
Kubernetes · 30 topics
DevOpsAdvanced Bash Scripting Study Notes
Bash · 30 topics
DevOpsApache Kafka Study Notes
Kafka · 30 topics
DevOpsDocker & Kubernetes Study Notes
YAML · 40 topics