A previous run was killed before it released the lock
CommonCtrl-C, a CI job timeout, a runner scaled away, a lost network connection, a laptop closed. Terraform tries to release on interrupt, but a hard kill leaves no opportunity — so the lock persists with the dead run's metadata still attached.
Confirm
# Read the Created and Who from the error, then check that run. # For CI, find the job that matches and confirm how it ended.
A creation time matching a run you know ended abnormally, and a `Who` naming a machine or job that is no longer running. Both together make this safe to clear.
Fix
- Confirm the holder is genuinely gone before doing anything else. That means checking the actual job or machine, not inferring from elapsed time.
- Then release it with the lock ID from the error message. Passing the ID rather than using a blanket unlock is deliberate — it fails if the lock has changed hands since you read the error.
terraform force-unlock <LOCK_ID>
Only after confirming the holder is dead. If you are guessing, you are choosing between a blocked pipeline and corrupted state, and the first is much cheaper.