Fix Terraform 'Error Acquiring the State Lock' with DynamoDB
The Error: Error Acquiring the State Lock
Terraform fails before even starting a plan:
Error: Error acquiring the state lock
Error message: AccessDeniedException: User: arn:aws:iam::123456789012:user/deploy
is not authorized to perform: dynamodb:PutItem on resource:
arn:aws:dynamodb:us-east-1:123456789012:table/terraform-locks
Or the table does not exist:
Error: Error acquiring the state lock
Error message: ResourceNotFoundException: Requested resource not found:
Table: terraform-locks not found
Unlike a stuck lock (where the lock exists but is orphaned), this error means Terraform cannot interact with the locking mechanism at all.
Root Cause
Terraform's S3 backend uses DynamoDB for state locking. The lock acquisition fails when:
- DynamoDB table does not exist — it was never created or was deleted
- IAM permissions are insufficient — the executing role lacks
dynamodb:PutItem,GetItem,DeleteItem - Wrong region or table name — backend config points to a non-existent table
- DynamoDB is throttling — the table's provisioned capacity is exceeded
Step-by-Step Fix
1. Verify the DynamoDB table exists
aws dynamodb describe-table \
--table-name terraform-locks \
--region us-east-1
If you get ResourceNotFoundException, create the table:
aws dynamodb create-table \
--table-name terraform-locks \
--attribute-definitions AttributeName=LockID,AttributeType=S \
--key-schema AttributeName=LockID,KeyType=HASH \
--billing-mode PAY_PER_REQUEST \
--region us-east-1
The table only needs one attribute: LockID (String), used as the partition key.
2. Check your backend configuration
In your Terraform backend block, verify the table name and region match:
terraform {
backend "s3" {
bucket = "my-tf-state"
key = "prod/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-locks" # Must match exactly
encrypt = true
}
}
Common mistakes: wrong region, typo in table name, or using a different AWS account.
3. Fix IAM permissions
The IAM role or user running Terraform needs these DynamoDB actions:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:GetItem",
"dynamodb:PutItem",
"dynamodb:DeleteItem",
"dynamodb:DescribeTable"
],
"Resource": "arn:aws:dynamodb:us-east-1:123456789012:table/terraform-locks"
}
]
}
Apply the policy:
aws iam put-user-policy \
--user-name deploy \
--policy-name terraform-lock-access \
--policy-document file://policy.json
4. Check for DynamoDB throttling
If you are using provisioned capacity and see ProvisionedThroughputExceededException:
# Check table metrics
aws cloudwatch get-metric-statistics \
--namespace AWS/DynamoDB \
--metric-name ThrottledRequests \
--dimensions Name=TableName,Value=terraform-locks \
--start-time 2026-03-30T00:00:00Z \
--end-time 2026-03-30T23:59:59Z \
--period 3600 \
--statistics Sum
# Switch to on-demand billing
aws dynamodb update-table \
--table-name terraform-locks \
--billing-mode PAY_PER_REQUEST \
--region us-east-1
5. Test lock acquisition manually
# Attempt to write a test item
aws dynamodb put-item \
--table-name terraform-locks \
--item '{"LockID": {"S": "test-lock"}}' \
--region us-east-1
# Clean up
aws dynamodb delete-item \
--table-name terraform-locks \
--key '{"LockID": {"S": "test-lock"}}' \
--region us-east-1
If this succeeds, the issue is in Terraform's backend config. If it fails, it is an IAM or network issue.
6. Bypass locking temporarily (emergency only)
terraform plan -lock=false
terraform apply -lock=false
This is dangerous in teams — only use when you are certain no one else is running Terraform.
Prevention Tips
- Create the DynamoDB table with your backend S3 bucket — use a bootstrap script or a separate Terraform root module for backend resources.
- Use
PAY_PER_REQUESTbilling on the lock table — it costs nearly nothing and eliminates throttling. - Include DynamoDB permissions in your CI role's base policy alongside S3 state bucket access.
- Tag the lock table so it does not get accidentally deleted during cleanup sweeps.
- Use
terraform initin CI before every plan/apply to catch backend misconfigurations early.
Was this article helpful?
Platform Engineer
Terraform enthusiast, platform builder, DRY advocate. I believe infrastructure should be versioned, reviewed, and deployed like any other code. GitOps or bust.
Related Articles
Terraform Remote State: S3 Backends, Locking, Workspaces, and State Surgery
Everything you need to know about Terraform remote state — from setting up S3 backends with locking to workspace strategies and emergency state surgery.
Terraform "Error: No Valid Credential Sources Found" On AWS — Fixing Authentication And Provider Configuration Issues
If you've spent any time with Terraform and AWS, you've almost certainly run into this gem at some point: It's one of those errors that looks simple but ca...
Terraform "Error: Cycle" In Resource Dependencies — How To Detect And Break Circular References
If you've spent any meaningful time with Terraform, you've probably encountered this at the worst possible moment: Everything was working fine, you added o...
Terraform Error: Invalid For_each Argument Must Be A Map Or Set Of Strings - Complete Fix Guide
If you've been working with Terraform's `for_each` argument, you've probably hit this error at least once. Don't worry – it's one of those frustrating but...
Fix Terraform State Lock Stuck After Failed Apply
Safely unlock Terraform state when a lock is stuck after a crashed apply, CI timeout, or interrupted operation.
Terraform CLI: Cheat Sheet
Terraform CLI cheat sheet with commands organized by workflow — init, plan, apply, destroy, state manipulation, imports, and workspace management.
More in Terraform
View all →Terraform Dynamic Blocks For Managing Variable Infrastructure Resources
If you've been working with Terraform for a while, you've probably hit that wall where you need to create resources with configurations that vary based on...
Writing Reusable Terraform Modules: A Practical Guide
Learn how to write Terraform modules that are actually reusable — with input validation, sensible defaults, and clean interfaces across environments.
Terraform from Zero to Production: Project Structure, Modules, State, and CI/CD
Build production-grade Terraform infrastructure — project structure, module design, state management, testing, and CI/CD pipeline integration.
Testing Terraform with Terratest: A Practical Guide
How to write unit and integration tests for Terraform modules using Terratest — because untested infrastructure is a liability.