This error occurs when Terraform cannot acquire a lock on your Azure Blob Storage state file because another process or operation already holds the lock. It typically happens when multiple pipelines run concurrently or when a previous operation terminated unexpectedly.
Terraform uses state locking via Azure Blob Storage leases to prevent concurrent modifications that could corrupt your infrastructure state. When one process acquires a lease on the state blob, other processes attempting to read or write the state will fail with this error. This is a safety mechanism to ensure only one Terraform operation modifies the state at a time. The lock persists until the operation completes or is forcefully released.
First, verify that no other Terraform operations are currently running against this state file:
# Check your local machine for any running terraform processes
ps aux | grep terraform
# Check Azure Portal for the state blob lease status
# Navigate to Storage Account > Containers > [your-container] > terraform.tfstate
# Look at the 'Leased state' columnIf another operation is running locally, wait for it to complete. If it's in a CI/CD pipeline, check your pipeline dashboard to see if a previous run is stuck.
If no active operation is running but the state remains locked:
1. Go to the Azure Portal
2. Navigate to your Storage Account
3. Select Containers
4. Open the container holding your state file (usually tfstate or similar)
5. Click on the terraform.tfstate blob
6. In the Overview panel, find the 'Lease state' field showing 'Leased'
7. Click the 'Break lease' button
8. Wait for the status to change to 'Broken'
9. Retry your Terraform operation
Alternatively, use the Azure CLI to break the lease programmatically:
az storage blob lease break \
-b terraform.tfstate \
-c tfstate \
--account-name "mystorageaccount" \
--account-key "your-storage-key"Replace:
- mystorageaccount with your storage account name
- tfstate with your container name
- Use --connection-string instead of --account-key if you prefer
If breaking the lease doesn't work, use Terraform's force-unlock command. First, identify the lock ID from your error message or by checking recent logs:
terraform force-unlock <LOCK_ID>The lock ID should be visible in your Terraform error output. Use this only as a last resort since it bypasses safety checks. Be absolutely certain no other operations are using the state file before forcing an unlock.
To prevent this error in the future, add lock timeout and retry flags to your Terraform commands:
terraform init -backend-config="..." -lock=true -lock-timeout=120s
terraform plan -lock=true -lock-timeout=120s
terraform apply -lock=true -lock-timeout=120sThis allows Terraform to retry acquiring the lock for up to 120 seconds instead of failing immediately. Adjust the timeout based on your typical operation duration.
The root cause prevention requires ensuring only one pipeline can run against a state file at a time. Implement one of these approaches:
GitHub Actions:
concurrency:
group: terraform-${{ github.ref }}
cancel-in-progress: falseGitLab CI:
resource_group: terraformAzure DevOps:
- Use a pipeline resource lock or manual approval gate
- Enable 'Use the auto-injected checkout task' and set concurrency settings
These prevent multiple pipeline runs from executing Terraform simultaneously on the same state.
Why locks are critical: Terraform state contains metadata about your infrastructure. Concurrent writes corrupt the state, causing Terraform to lose track of resources, leading to duplicate creation, deletion of in-use resources, or crashes.
Azure Blob Lease mechanism: Azure Blob Storage has a native leasing system. Terraform acquires a lease when starting an operation and releases it on completion. Unlike traditional file locks, leases can become stuck if the process terminates unexpectedly.
Lock timeout behavior: The -lock-timeout flag tells Terraform to retry acquiring the lock every 100ms until the timeout expires. If still locked after the timeout, the operation fails. This is useful for handling transient network issues but won't solve stuck locks from crashed processes.
Terraform 0.14 bug: In Terraform 0.14.8, the Azure backend had a known issue where -lock-timeout was ignored. This was fixed in 0.15.0. If you're on 0.14.x and experiencing persistent lock issues, upgrade to 0.15+ or manually break leases via the Azure Portal.
Disabling locks (not recommended): You can use -lock=false to skip locking entirely, but this is extremely dangerous. Multiple writers can corrupt state, leading to infrastructure inconsistencies. Only disable locks in emergency scenarios with explicit team communication.
State file location: Always store Terraform state in remote backends (Azure Blob Storage, S3, etc.) in production. Local state files can be accidentally committed to git, exposing sensitive data, and provide no locking mechanism for team collaboration.
Error: Error installing helm release: cannot re-use a name that is still in use
How to fix "release name in use" error in Terraform with Helm
Error: Error creating GKE Cluster: BadRequest
BadRequest error creating GKE cluster in Terraform
Error: External program failed to produce valid JSON
External program failed to produce valid JSON
Error: Unsupported argument in child module call
How to fix "Unsupported argument in child module call" in Terraform
Error: network is unreachable
How to fix "network is unreachable" in Terraform