This error occurs when Terraform fails to list AWS resources during plan or apply operations. Common causes include missing IAM permissions, connectivity issues, or API throttling. Fix it by verifying credentials, checking IAM policies, and reviewing API rate limits.
The "error listing resources: operation error" message appears when the Terraform AWS provider fails to enumerate resources from AWS APIs. This typically happens during data source lookups, when Terraform queries AWS to discover existing resources, check state, or apply changes. The error usually masks the underlying API failureβit could be an authentication error, permission error, service limit, or networking issue. This error is common in S3 backends (ListObjectsV2), service enumeration (LakeFormation, RDS, DynamoDB), and when querying data sources with insufficient permissions.
Set the TF_LOG environment variable to DEBUG to see what operation actually failed:
export TF_LOG=DEBUG
terraform plan 2>&1 | grep -A 10 "operation error"Or use TRACE for even more detail:
export TF_LOG=TRACE
terraform plan > terraform.log 2>&1
grep "operation error" terraform.logLook for the specific AWS API operation (e.g., "S3: ListObjectsV2", "EC2: DescribeInstances"). This tells you exactly which permission is missing or which service is failing.
Test that your credentials work:
aws sts get-caller-identityThis should return your AWS Account ID, User ARN, and User ID. If it fails or returns nothing:
1. For local development: Check ~/.aws/credentials and ~/.aws/config
2. For CI/CD: Verify AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables
3. For EC2/Lambda: Ensure the IAM role is attached
4. For temporary credentials: Check expiration with:
aws sts get-session-token # If using MFA
# Or check STS assume-role session tokens in credentials file for expiration timeIf credentials are expired, refresh them or use a service with automatic credential rotation (IAM roles on EC2, IRSA in Kubernetes, etc.).
Once you know the specific operation from the debug logs (e.g., "S3: ListObjectsV2"), verify your IAM policy includes it:
# Check which user/role Terraform is using
aws sts get-caller-identity
# View inline and attached policies
aws iam list-attached-user-policies --user-name YOUR_USER
aws iam get-user-policy --user-name YOUR_USER --policy-name POLICY_NAMEEnsure your policy includes the required action. For example, if you're hitting S3 bucket errors:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetObject",
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::your-bucket",
"arn:aws:s3:::your-bucket/*"
]
}
]
}For general Terraform AWS operations, ensure policies include ec2:Describe* and related read operations on the resources you're managing.
If the error is transient, it may be API throttling. Terraform automatically retries, but you can adjust retry behavior:
# First, try a simple retry
terraform planIf it succeeds on retry, the issue was likely throttling. For production, use an S3 backend with DynamoDB for state locking, which includes built-in retry logic.
If you're in an account with high API usage, request a service quota increase:
# Check current API call quotas in AWS Service Quotas console
# https://console.aws.amazon.com/servicequotasCommon limit causes:
- First Terraform init/plan in a new workspace (AWS lists all resources)
- Importing many resources at once
- Concurrent Terraform operations in the same AWS account
If you're using an S3 backend, the error may be during state operations. Check:
# Test S3 bucket access
aws s3 ls s3://your-bucket/path/to/terraform.tfstate
# Test DynamoDB state lock table access (if using state locking)
aws dynamodb scan --table-name terraform-locks --max-items 1Ensure your IAM policy includes:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:ListBucket"],
"Resource": "arn:aws:s3:::your-terraform-bucket"
},
{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject", "s3:DeleteObject"],
"Resource": "arn:aws:s3:::your-terraform-bucket/*"
},
{
"Effect": "Allow",
"Action": [
"dynamodb:DescribeTable",
"dynamodb:GetItem",
"dynamodb:PutItem",
"dynamodb:DeleteItem"
],
"Resource": "arn:aws:dynamodb:REGION:ACCOUNT:table/terraform-locks"
}
]
}Ensure you're targeting the correct AWS region:
# Check your Terraform provider config
grep -A 3 "provider "aws"" *.tf
# Verify AWS_REGION environment variable
echo $AWS_REGION
# Test connectivity to AWS endpoints
aws ec2 describe-instances --region us-east-1If using a VPC endpoint or private network, ensure:
- VPC endpoints are enabled for the services you're accessing
- Security groups allow outbound HTTPS (port 443) to AWS API endpoints
- No firewall rules are blocking AWS API domains
For LocalStack or Moto (local testing), ensure the endpoint URL is correctly configured:
provider "aws" {
region = "us-east-1"
access_key = "test"
secret_key = "test"
skip_credentials_validation = true
skip_metadata_api_check = true
# Only for LocalStack
endpoints {
s3 = "http://localhost:4566"
ec2 = "http://localhost:4566"
}
}Debug environment variable strategies: Using TF_LOG=DEBUG shows one log line per API operation. For debugging specific failures, pipe to grep or save to a file. TF_LOG_CORE=DEBUG shows Terraform core internals separately from provider-specific logs. If you need to share logs with maintainers, set TF_LOG=DEBUG and mask your AWS account ID, resource IDs, and credentials before posting.
State file vs. resource listing: "Error listing resources" can occur in two contexts: (1) During data source evaluation (user explicitly queries data), or (2) During refresh, when Terraform automatically queries current state. If your error only happens during refresh, the issue is likely stale state or missing resources. Use terraform refresh to force a state sync.
Cross-account and cross-region scenarios: If you use assume_role to switch AWS accounts or access multiple regions, ensure each role has the necessary permissions in its target account/region. The error "operation error" often masks a "role not found" or "no permission in this region" issue.
Terraform Cloud vs. self-hosted backends: In Terraform Cloud, if you see "operation error" without details, check the Run logs (not the state logs). The actual error may be in a different section of the Run details page. Self-hosted backends should be checked for disk space, network connectivity, and credential validity.
Error: Error rendering template: template not found
How to fix "template not found" error in Terraform
Error: Error generating private key
How to fix 'Error generating private key' in Terraform
Error creating Kubernetes Service: field is immutable
How to fix "field is immutable" errors in Terraform
Error: Error creating local file: open: permission denied
How to fix "Error creating local file: permission denied" in Terraform
Error: line endings have changed from CRLF to LF
Line endings have changed from CRLF to LF in Terraform