UnauthorizedOperation errors in Terraform indicate missing AWS IAM permissions. Identify the specific action being denied through debug logs or encoded error messages, then add the required permission to your IAM policy.
When Terraform attempts to create, modify, or delete AWS resources, your AWS credentials must have the appropriate IAM permissions. An UnauthorizedOperation error occurs when the IAM user or role running Terraform lacks permission to perform a specific AWS API action. AWS returns either a clear error message stating the missing permission (e.g., "User is not authorized to perform: iam:PassRole") or an encoded message that must be decoded. The error appears as HTTP 403 Forbidden in the AWS API response. This error is common when moving between environments (sandbox to production), updating Terraform AWS provider versions that require new permissions, or using a restricted IAM policy that follows the principle of least privilege.
Run Terraform with debug logging enabled to see the exact AWS API call and error details:
TF_LOG=debug terraform apply -target=aws_resource_type.name 2>&1 | tee terraform-debug.logThe -target flag reduces output volume by focusing on a single resource. Search the debug log for "Error:", "denied", or "UnauthorizedOperation" to find the specific AWS action (e.g., ec2:RunInstances, iam:PassRole, rds:CreateDBInstance).
If the error includes an "Encoded authorization failure message" with a long random-looking string, decode it with the AWS CLI to see which permission is missing:
aws sts decode-authorization-message --encoded-message 'COPY_THE_LONG_STRING_FROM_ERROR' --query DecodedMessage --output textThis reveals the exact IAM action that failed, such as "ec2:DescribeTags" or "iam:PassRole".
Add the required IAM action to your user or role's policy. For example, if the error indicates missing ec2:RunInstances permission:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ec2:RunInstances",
"Resource": "*"
}
]
}Follow the principle of least privilege by restricting resources with specific ARNs instead of "*" where possible.
Check that Terraform is using the correct AWS profile and credentials:
# View current AWS profile
echo $AWS_PROFILE
# List available profiles
aws configure list-profiles
# Test credentials for the profile
aws sts get-caller-identity --profile your-profileEnsure your Terraform AWS provider configuration matches the profile with proper permissions:
provider "aws" {
region = "us-east-1"
profile = "your-profile"
}If you're in an AWS Organization or have permission boundaries configured, verify they don't block the action:
For Organizations SCPs:
- Log in with admin credentials and check the IAM service for applied SCPs
- SCPs are restrictive policies applied at the organization or account level
- Contact your organization administrator if your required action is blocked
For permission boundaries:
- Check the IAM user or role details for attached permission boundaries
- Boundaries override explicit Allow statements, so they must grant the action
- Request your administrator to update the boundary policy if needed
The AWS IAM Policy Simulator can test if a policy allows an action without applying changes.
If the error started after upgrading your Terraform AWS provider, check the release notes for new required permissions:
# Check your current provider version
terraform version
# View provider release notes
# https://github.com/hashicorp/terraform-provider-aws/releasesProvider updates sometimes add new IAM actions to existing resources. Update your IAM policies to include these newly required actions.
When running Terraform in CI/CD pipelines, ensure the IAM role or user assumes has all required permissions. Cross-account access requires additional trust relationships and AssumeRole permissions.
Rootless Docker and containerized Terraform execution may require additional permissions for CloudWatch Logs (logs:*) and VPC endpoint access. SELinux systems need appropriate context for credential file access.
If credentials become compromised, AWS applies the "AWSCompromisedKeyQuarantineV2" policy which denies most actions. Replace credentials immediately and inform your AWS account administrator.
For large-scale deployments, use the IAM Access Analyzer to generate least-privilege policies based on actual CloudTrail logs of your Terraform operations.
Error: Error installing helm release: cannot re-use a name that is still in use
How to fix "release name in use" error in Terraform with Helm
Error: Error creating GKE Cluster: BadRequest
BadRequest error creating GKE cluster in Terraform
Error: External program failed to produce valid JSON
External program failed to produce valid JSON
Error: Unsupported argument in child module call
How to fix "Unsupported argument in child module call" in Terraform
Error: network is unreachable
How to fix "network is unreachable" in Terraform