Terraform cannot find valid AWS credentials to authenticate with the AWS Provider. This occurs when credentials are not configured via environment variables, AWS CLI credentials file, IAM roles, or provider settings.
This error indicates that Terraform has attempted to authenticate with AWS but could not locate any valid credentials through any of its supported authentication methods. The AWS Provider checks multiple credential sources in a specific order, and if none are found or all are invalid, Terraform raises this error. This is a critical blocker that prevents Terraform from communicating with AWS to plan or apply infrastructure changes.
The fastest way to provide credentials is to set environment variables:
export AWS_ACCESS_KEY_ID="your-access-key-id"
export AWS_SECRET_ACCESS_KEY="your-secret-access-key"
export AWS_DEFAULT_REGION="us-east-1"Verify credentials are set:
echo $AWS_ACCESS_KEY_ID
echo $AWS_SECRET_ACCESS_KEYThen run Terraform:
terraform init
terraform planNote: On Windows, use set instead of export.
If you have not already done so, configure the AWS CLI:
aws configureYou will be prompted for:
- AWS Access Key ID
- AWS Secret Access Key
- Default region
- Default output format
This creates or updates ~/.aws/credentials and ~/.aws/config.
Terraform will automatically find these credentials. Verify by running:
terraform initTo use a specific named profile, add to your Terraform provider:
provider "aws" {
region = "us-east-1"
profile = "default"
}If running Terraform from an EC2 instance, attach an IAM role to the instance:
1. Create an IAM role with appropriate permissions (e.g., AdministratorAccess for testing)
2. Attach the role to your EC2 instance via the AWS Console or CLI
3. Do NOT set AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY environment variables
4. Terraform will automatically use the EC2 instance metadata service to retrieve temporary credentials
Verify the instance has the role:
aws sts get-caller-identityIf successful, Terraform should work without explicit credentials:
terraform init
terraform planThis is the recommended approach for CI/CD runners on AWS infrastructure.
In AWS Provider version 4.0 and later, if you explicitly set a profile in the provider configuration, it will NOT fall back to environment variables if that profile is not found or invalid.
If you have this in your code:
provider "aws" {
region = "us-east-1"
profile = "nonexistent-profile"
}Verify the profile exists in your ~/.aws/credentials file:
cat ~/.aws/credentialsYou should see a section like:
[nonexistent-profile]
aws_access_key_id = ...
aws_secret_access_key = ...If the profile does not exist, either:
- Add it to your credentials file with aws configure --profile nonexistent-profile
- Remove the profile line from your Terraform provider to use the default profile
- Set environment variables explicitly (which will be ignored if profile is set)
On Unix-like systems, the ~/.aws/credentials file must have correct permissions:
chmod 600 ~/.aws/credentials
chmod 700 ~/.awsVerify permissions:
ls -la ~/.aws/credentialsOutput should show:
-rw------- 1 user user ... ~/.aws/credentialsIf permissions are too open or too restrictive, AWS SDK may not be able to read the file.
For testing purposes, you can hardcode credentials in your provider block:
provider "aws" {
region = "us-east-1"
access_key = "YOUR_ACCESS_KEY"
secret_key = "YOUR_SECRET_KEY"
}WARNING: This is NOT recommended for production. If this file is committed to version control, your credentials will be exposed.
Better approach: Use variables with a .tfvars file:
variable "aws_access_key" {
type = string
sensitive = true
}
variable "aws_secret_key" {
type = string
sensitive = true
}
provider "aws" {
region = "us-east-1"
access_key = var.aws_access_key
secret_key = var.aws_secret_key
}Create terraform.tfvars (do not commit this file):
aws_access_key = "YOUR_ACCESS_KEY"
aws_secret_key = "YOUR_SECRET_KEY"Add .tfvars files to .gitignore.
AWS Provider v4.0 and later changed credential precedence behavior. Previously, if a profile was set in the provider configuration but the profile was invalid, the provider would fall back to environment variables. This is no longer the case. If you set an explicit profile, it must exist and be valid, or Terraform will fail with the 'no valid credential sources' error. For CI/CD environments, use dynamic provider credentials with OpenID Connect (OIDC) for temporary, time-bound credentials instead of long-lived access keys. Terraform Cloud and HCP Terraform support AWS OIDC integration, which eliminates the need to store AWS access keys in CI/CD systems.
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