Skip to content
Latchkey

Terraform "Error loading state" AccessDenied in CI

Terraform reached the state backend but the request to read the state object was denied. The runner authenticated, yet its role lacks the read permission (for example s3:GetObject) on the state path.

What this error means

init or plan stops with "Error: Error loading state:" followed by an "AccessDenied" (403) from the backend when fetching the state file.

Terraform
Error: Error loading state:
    AccessDenied: Access Denied
    status code: 403, request id: 8A1F..., host id: ...

Terraform failed to load the state from the "s3" backend.

Common causes

The role lacks read permission on the state object

The CI principal can call the backend but is missing s3:GetObject (and often s3:ListBucket) on the state key or prefix.

A bucket policy or KMS key blocks the reader

A restrictive bucket policy or a KMS key without a decrypt grant for the runner role denies the read.

How to fix it

Grant read access to the state path

  1. Add s3:GetObject and s3:ListBucket for the state bucket/prefix to the CI role.
  2. If the object is KMS-encrypted, grant kms:Decrypt on the key.
  3. Re-run init to confirm state loads.
IAM policy
{
  "Effect": "Allow",
  "Action": ["s3:GetObject", "s3:ListBucket"],
  "Resource": [
    "arn:aws:s3:::acme-tf-state",
    "arn:aws:s3:::acme-tf-state/app/*"
  ]
}

Fix the assumed identity

Confirm the CI job assumes the role that has state access, not a default or wrong-account identity.

How to prevent it

  • Grant least-privilege state read/write to the CI role.
  • Include KMS decrypt when state is encrypted.
  • Verify the assumed role before running init.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →