Terraform cannot find valid AWS credentials to authenticate with AWS. This happens when credentials are not configured via environment variables, shared credentials file, IAM roles, or provider configuration.
This error occurs when Terraform's AWS Provider cannot locate valid AWS credentials through any of its credential source mechanisms. Terraform searches for credentials in a specific order: environment variables, shared credentials file (~/.aws/credentials), AWS config file (~/.aws/config), EC2 instance IAM roles, and explicit provider configuration. When none of these sources contain valid credentials, the provider cannot authenticate API requests to AWS.
First, test if AWS credentials are working at all:
aws sts get-caller-identityIf this command fails, your AWS credentials are not properly configured. If it succeeds, the credentials exist but Terraform cannot find them.
The most reliable method for Terraform:
export AWS_ACCESS_KEY_ID=your_access_key_id
export AWS_SECRET_ACCESS_KEY=your_secret_access_key
export AWS_REGION=us-east-1 # Optional, but recommendedVerify they are set:
echo $AWS_ACCESS_KEY_ID
echo $AWS_SECRET_ACCESS_KEYThen run Terraform again:
terraform planCreate or edit ~/.aws/credentials:
[default]
aws_access_key_id = your_access_key_id
aws_secret_access_key = your_secret_access_key
[profile-name]
aws_access_key_id = another_access_key_id
aws_secret_access_key = another_secret_access_keyEnsure file permissions are correct (readable only by you):
chmod 600 ~/.aws/credentialsThen specify the profile in your Terraform provider:
provider "aws" {
region = "us-east-1"
profile = "default"
}There is a known bug where extra whitespace or empty profiles in ~/.aws/credentials can interfere with credential detection. Try:
1. Backup your credentials file: cp ~/.aws/credentials ~/.aws/credentials.bak
2. Edit the file and remove all empty sections or extra whitespace
3. Keep only the profile(s) you are actually using
4. Verify file format is exact with no trailing spaces:
cat -A ~/.aws/credentials5. Start a fresh terminal session and test again
If running Terraform on an EC2 instance, use instance profiles instead:
1. Create an IAM role with necessary permissions (e.g., AmazonEC2FullAccess)
2. Create an instance profile from that role
3. Attach the instance profile to your EC2 instance
4. No credentials needed in Terraform - it will auto-detect the instance role
Terraform provider configuration:
provider "aws" {
region = "us-east-1"
# Credentials will be auto-detected from instance profile
}AWS Provider v4.0+ changed credential precedence behavior. If upgrading from v3.x:
1. Check your current provider version:
terraform providers2. If you explicitly set a profile in the provider block but that profile doesn't exist or has no valid credentials, v4.0+ will fail (v3.x would fall back to env vars)
3. Solution: Either remove the explicit profile setting, or ensure the profile exists with valid credentials
# Option 1: Remove explicit profile
provider "aws" {
region = "us-east-1"
}
# Option 2: Ensure profile exists and has valid credentials
provider "aws" {
region = "us-east-1"
profile = "myprofile" # Must exist in ~/.aws/credentials
}AWS signature validation is time-sensitive. If running Terraform in a VM (Vagrant, VirtualBox, etc.) that has been up for days, the clock may drift:
# Check system time
date
# Sync clock (requires NTP or manual adjustment)
sudo ntpdate -s time.nist.gov # Linux
# or
sudo sntp -s time.apple.com # macOSIf using Vagrant/VirtualBox, restart the VM to force clock sync:
vagrant halt
vagrant upAWS Provider v4.0 Breaking Change: In v3.x, if you set an explicit profile that didn't exist, Terraform would fall back to environment variables. In v4.0+, it will error instead. If migrating from v3.x to v4.0+, audit your provider configurations.
EC2 Metadata Service (IMDS): When running Terraform from EC2 instances (especially in Terraform Cloud or Enterprise), ensure IMDSv2 is enabled with proper http-put-response-hop-limit configuration. Some container environments may have IMDS disabled.
IAM Permission Errors: This error is specifically about credential *sources*, not permissions. If credentials are found but you get a different error like InvalidClientTokenId or AccessDenied, that's a permissions issue, not a credentials source issue.
Rate Limiting in CI/CD: Adding -parallelism=4 to terraform commands can help reduce intermittent failures when credentials are being accessed from shared metadata services.
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