Terraform S3 Access Denied — How to Fix It (2026)
Getting AccessDenied when Terraform tries to read or write your S3 backend? Here's every cause and the exact fix.
Terraform hits S3 Access Denied most often during init (reading state) or apply (writing state). The error looks like this:
Error: Failed to get existing workspaces: S3 bucket does not have versioning enabled
Error: AccessDenied: Access Denied
status code: 403
Here's how to find the cause and fix it.
The 5 Most Common Causes
- IAM user/role doesn't have S3 permissions
- S3 bucket policy blocks the IAM principal
- Wrong region configured
- Bucket doesn't exist or typo in bucket name
- KMS encryption — IAM has S3 access but not KMS decrypt
Fix 1: Check IAM Permissions
Your Terraform runner needs these S3 permissions at minimum for remote state:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject",
"s3:ListBucket",
"s3:GetBucketVersioning"
],
"Resource": [
"arn:aws:s3:::your-terraform-state-bucket",
"arn:aws:s3:::your-terraform-state-bucket/*"
]
}
]
}Test quickly:
aws s3 ls s3://your-terraform-state-bucket
aws sts get-caller-identity # confirm which IAM entity is runningFix 2: Check Bucket Policy
Even with the right IAM permissions, a restrictive bucket policy can block access.
aws s3api get-bucket-policy --bucket your-terraform-state-bucketIf the bucket policy has an explicit Deny or doesn't have an Allow for your principal — that's your issue.
Add your IAM role/user to the bucket policy:
{
"Principal": {
"AWS": "arn:aws:iam::123456789:role/terraform-runner-role"
},
"Action": ["s3:GetObject", "s3:PutObject", "s3:ListBucket"],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::your-terraform-state-bucket",
"arn:aws:s3:::your-terraform-state-bucket/*"
]
}Fix 3: KMS Encryption
If your S3 bucket uses KMS encryption (SSE-KMS), the IAM role also needs KMS permissions:
{
"Effect": "Allow",
"Action": [
"kms:GenerateDataKey",
"kms:Decrypt"
],
"Resource": "arn:aws:kms:us-east-1:123456789:key/your-kms-key-id"
}Check if the bucket uses KMS:
aws s3api get-bucket-encryption --bucket your-terraform-state-bucketFix 4: DynamoDB Lock Table
If using DynamoDB for state locking, you also need these permissions:
{
"Effect": "Allow",
"Action": [
"dynamodb:GetItem",
"dynamodb:PutItem",
"dynamodb:DeleteItem"
],
"Resource": "arn:aws:dynamodb:us-east-1:123456789:table/terraform-state-lock"
}Fix 5: Wrong Region
terraform {
backend "s3" {
bucket = "your-terraform-state-bucket"
key = "prod/terraform.tfstate"
region = "us-east-1" # must match bucket region
}
}If the bucket is in ap-south-1 but backend says us-east-1 — you get Access Denied.
Check bucket region:
aws s3api get-bucket-location --bucket your-terraform-state-bucketQuick Debug Checklist
# Who am I?
aws sts get-caller-identity
# Can I list the bucket?
aws s3 ls s3://your-bucket
# Can I read a specific key?
aws s3 cp s3://your-bucket/path/terraform.tfstate /tmp/test.tfstate
# Check bucket encryption
aws s3api get-bucket-encryption --bucket your-bucketWork through this list top to bottom — 95% of S3 Access Denied errors are fixed by step 2.
Resources
Stay ahead of the curve
Get the latest DevOps, Kubernetes, AWS, and AI/ML guides delivered straight to your inbox. No spam — just practical engineering content.
Related Articles
Terraform Error Acquiring the State Lock: Causes and Fix
Terraform state lock errors can block your entire team. Learn why they happen, how to safely unlock state, and how to prevent lock conflicts for good.
AWS ALB Showing Unhealthy Targets — How to Fix It
Fix AWS Application Load Balancer unhealthy targets. Covers health check misconfigurations, security group issues, target group problems, and EKS-specific ALB controller debugging.
AWS ECS Task Keeps Stopping — How to Fix It (2026)
Your ECS task starts and then immediately stops or keeps restarting. Here's every reason this happens and how to debug and fix it.