Fixing 'Error acquiring the state lock' in Terraform

intermediate๐Ÿ—๏ธ Terraform2026-03-16| Linux, macOS, Windows with Terraform CLI, remote state (e.g., AWS S3 and DynamoDB backend)

Error Message

Error acquiring the state lock
#terraform#state#lock#dynamodb

TL;DR: Quick Fix

When you hit the "Error acquiring the state lock" message, it usually means another Terraform operation is in progress, or a previous one crashed and left a stale lock. For a quick resolution in emergencies, especially if you're certain no other legitimate operation is running, you can often force-unlock the state. Grab the lock ID from the error message and run:

terraform force-unlock <LOCK_ID>

Proceed with extreme caution when using force-unlock, as improper use can lead to state corruption if another process genuinely holds the lock.

Detailed Root Cause

Terraform uses state locking to prevent concurrent operations from corrupting your state file. When you run terraform plan, apply, or destroy, Terraform attempts to acquire a lock on the state. This mechanism ensures that only one person or process can modify the infrastructure at any given time. With remote backends like AWS S3, a separate service, typically DynamoDB, is used to manage these locks.

The "Error acquiring the state lock" message pops up for several reasons:

  • Concurrent Runs: Someone else (or another automated pipeline) is running a Terraform command on the same state file simultaneously.
  • Crashed Operations: A previous Terraform command failed mid-execution due to a crash, network interruption, or manual termination (e.g., Ctrl+C). The lock wasn't released cleanl.
  • Network Issues: Terraform cannot communicate with the locking mechanism (e.g., DynamoDB) to acquire or verify the lock.
  • Permissions Problems: The IAM user or role executing Terraform lacks the necessary permissions to interact with the DynamoDB lock table or the S3 state bucket.

In essence, Terraform is doing its job by refusing to proceed, protecting your infrastructure state from potential damage. Our job is to figure out why it thinks it can't get that lock.

Fix Approaches

Approach 1: Use terraform force-unlock (Carefully!)

This is often the quickest way to resolve a stale lock, but it carries risks. Only use this if you're absolutely sure no other legitimate Terraform operation is active.

  • Identify the Lock ID: The error message itself usually contains the lock ID. It looks something like a UUID (e.g., 0a1b2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d).

Error: Error acquiring the state lock

Error message: Failed to get lock: An error occurred (ConditionalCheckFailedException) when calling the PutItem operation: The conditional request failed Lock Info: ID: a1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d Path: some-s3-bucket/path/to/terraform.tfstate Operation: OperationTypeApply Who: user@hostname Version: 1.0.0 Created: 2023-10-27 08:00:00 +0000 UTC Info:

Terraform acquires a state lock to protect the state from being simultaneously updated by multiple working copies. If you believe this lock is erroneous, you may use the "terraform force-unlock" command to release it.

  
  - 
    **Run `terraform force-unlock`:**

    ```bash
terraform force-unlock a1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d

Terraform will ask for confirmation. Type yes to proceed.

Approach 2: Check for Active Terraform Processes

Before force-unlocking, it's wise to ensure no other Terraform processes are actually running, especially in automated environments or if other team members might be working.

  • Locally: Check your own machine's running processes. On Linux/macOS:

ps aux | grep terraform


Look for any lingering `terraform apply` or `terraform plan` processes. Terminate them if found using `kill <PID>`.

  
  - 
    **CI/CD Pipelines:** If this error is from a CI/CD job, check the pipeline logs and status. There might be a stuck job that needs to be manually cancelled or restarted.

  

### Approach 3: Verify DynamoDB Lock Table (for AWS S3 backend)
If you're using AWS S3 for remote state, Terraform uses a DynamoDB table for locking. Inspecting this table can reveal what's holding the lock.

  - 
    **Access DynamoDB:** Go to the AWS Management Console, navigate to DynamoDB, and find the table Terraform uses for locking (often named `terraform-lock` or similar, configured in your backend). Look at the items in the table.

    Alternatively, use the AWS CLI:

    ```bash
aws dynamodb scan --table-name your-terraform-lock-table --query 'Items[*].LockID.S'

This will list active lock IDs. Compare them to the one in your error message.

  • Manually Remove Stale Lock Entry (Extreme Caution!): If you find a lock entry in DynamoDB that corresponds to your error message and you're absolutely certain it's stale (i.e., no actual Terraform operation is active), you can delete it directly from the DynamoDB console or using the AWS CLI. This is essentially what terraform force-unlock does.

aws dynamodb delete-item
--table-name your-terraform-lock-table
--key '{"LockID": {"S": "a1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d"}}'


Only delete if you fully understand the implications. Deleting an active lock can lead to data corruption.

  

### Approach 4: Network Connectivity and IAM Permissions
A more fundamental issue might be preventing Terraform from even checking the lock.

  - 
    **Check Network Connectivity:** Ensure the machine running Terraform has network access to AWS S3 and DynamoDB endpoints. This involves checking security groups, NACLs, VPC endpoints, or proxy settings.

  
  - 
    **Verify IAM Permissions:** The IAM entity (user or role) executing Terraform needs specific permissions for the S3 bucket (`s3:GetObject`, `s3:PutObject`, `s3:DeleteObject`, `s3:ListBucket`) and the DynamoDB lock table (`dynamodb:GetItem`, `dynamodb:PutItem`, `dynamodb:DeleteItem`, `dynamodb:DescribeTable`). A missing permission here will block state locking and unlocking.

    ```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:DeleteObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::your-terraform-state-bucket",
                "arn:aws:s3:::your-terraform-state-bucket/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "dynamodb:GetItem",
                "dynamodb:PutItem",
                "dynamodb:DeleteItem",
                "dynamodb:DescribeTable"
            ],
            "Resource": "arn:aws:dynamodb:<REGION>:<ACCOUNT_ID>:table/your-terraform-lock-table"
        }
    ]
}

Review the attached policies and ensure they grant the necessary access. Use aws sts get-caller-identity to confirm which IAM entity Terraform is using.

Verification Steps

After attempting a fix, it's crucial to verify that the lock issue is resolved and Terraform can operate normally.

  • Run terraform plan: Execute a simple plan. If the lock was successfully released or acquired, this command should run without the lock error.

terraform plan

  
  - 
    **Run `terraform apply -auto-approve -refresh=false` (if safe):** For a more thorough check in a non-production environment or if your plan is truly a no-op, you might attempt a quick apply. The `-refresh=false` flag can speed this up if you just want to test the locking mechanism, not refresh the state.

    ```bash
terraform apply -auto-approve -refresh=false
  • Monitor DynamoDB: If you're observing the DynamoDB table, you should see the lock item appear when plan or apply starts and disappear once the operation completes successfully.

Further Reading

Related Error Notes