Terraform Error: 'reference to undeclared provider' Aliased Provider Not Configured
Fix Terraform's 'reference to undeclared provider' / invalid provider alias error: declare the aliased provider, wire configuration_aliases in modules, and pass providers correctly.
- #terraform
- #iac
- #troubleshooting
- #errors
Stuck on this Terraform error? Get the free incident triage checklist
A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.
Exact Error Message
╷
│ Error: reference to undeclared provider
│
│ on main.tf line 24, in resource "aws_s3_bucket" "replica":
│ 24: provider = aws.us_west
│
│ There is no provider "aws" with alias "us_west".
│
│ To reference a provider configuration, you must first declare it in a
│ required_providers block and a provider block with a matching alias.
╵
You may also see the module-facing variant Provider configuration not present or provider aws.us_west is undefined when a child module expects an aliased provider that the root never passed in.
What It Means
Terraform lets you configure the same provider more than once by giving each extra configuration an alias. A resource, data source, or module then opts into a specific configuration with provider = aws.us_west. This error means you referenced an alias that was never declared. Terraform validated the reference before planning and could not find a provider "aws" block whose alias matches, so it stops.
The most common trigger is multi-region or multi-account AWS setups where a second provider block was forgotten, misspelled, or defined inside a module that cannot see it. The default (unaliased) provider is separate from every aliased one, so having a plain provider "aws" {} block does not satisfy a reference to aws.us_west.
Common Causes
- The aliased
providerblock was never written, only referenced on a resource. - A typo: the resource says
aws.us_westbut the block declaresalias = "uswest". - A child module uses
provider = aws.us_westwithout aconfiguration_aliasesentry in itsrequired_providers. - The root module forgot the
providers = { ... }map when calling a module that needs an aliased provider. - The alias lives in a different module scope; aliases do not inherit automatically into child modules.
Diagnostic Commands
Validate the configuration to surface every undeclared reference at once:
terraform validate
List which providers Terraform thinks the configuration requires:
terraform providers
Search the codebase for the alias to see where it is declared versus referenced:
grep -rn "aws.us_west\|alias" *.tf modules/
Run an init and plan to confirm the reference resolves after fixing:
terraform init
terraform plan
Step-by-Step Resolution
- Declare the aliased provider in the root module. Every alias needs its own
providerblock:
provider "aws" {
region = "us-east-1"
}
provider "aws" {
alias = "us_west"
region = "us-west-2"
}
- Reference it exactly, matching the alias string character-for-character:
resource "aws_s3_bucket" "replica" {
provider = aws.us_west
bucket = "example-replica-bucket"
}
- If the reference is inside a child module, declare the alias with
configuration_aliasesso the module knows it expects to be handed that provider:
# modules/replication/versions.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
configuration_aliases = [aws.us_west]
}
}
}
- Pass the configured provider from the root when calling that module. Without the
providersmap, the child sees no aliased provider:
module "replication" {
source = "./modules/replication"
providers = {
aws.us_west = aws.us_west
}
}
- Re-initialize so Terraform records the provider requirements, then validate:
terraform init
terraform validate
Success! The configuration is valid.
- Plan to confirm the resource now binds to the correct region/account.
Prevention
- Keep all provider blocks (default and aliased) in one
providers.tffile so missing aliases are obvious. - Always add
configuration_aliasesin a module’srequired_providersfor any provider the module references by alias. - Pass providers explicitly with the
providers = {}map when a module needs a non-default configuration; do not rely on implicit inheritance. - Standardize alias names (for example
aws.us_east_1,aws.us_west_2) across the repo to avoid typos. - Run
terraform validatein CI on every change to catch undeclared references before apply.
Related Errors
Reference to undeclared input variable— a missingvariableblock, the input-variable analogue of this error.Provider configuration not present— a passed-through provider was removed from a module’s inputs but is still referenced.Duplicate provider configuration— two provider blocks share the same alias (or both omit one).Invalid provider configuration— the provider block exists but a required argument is missing or malformed.
Frequently Asked Questions
Why does my default provider "aws" block not satisfy aws.us_west? The default (unaliased) provider and every aliased provider are distinct configurations. A resource referencing aws.us_west needs a provider "aws" block with alias = "us_west" specifically.
Do child modules inherit aliased providers automatically? No. Only the default provider is inherited implicitly. Aliased providers must be declared with configuration_aliases and passed in via the providers = {} map on the module call.
How do I fix this in a reusable module? Add the alias to the module’s required_providers using configuration_aliases = [aws.us_west], then have every caller pass the provider explicitly. For prompts that scaffold multi-provider modules, see the Terraform prompt library.
Can a typo really cause this? Yes. The alias is matched by exact string, so us_west versus uswest will fail. Run terraform providers and grep for the alias to compare declaration and reference.
Where do I go for more Terraform provider fixes? See the full Terraform guides for related init, provider, and module troubleshooting.
Fixed it? Get 500 Terraform & DevOps AI prompts — free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.
Stuck on this? Start guided troubleshooting
Open an interactive diagnostic session with this error already loaded. Work a step-by-step plan, record what each check returns, land on a root cause, and export a clean incident summary — no account needed to start.
Did this fix your issue?
Solved it a different way?
Share the fix that worked for you — reviewed, then published to help the next engineer.
That looks like it may contain a secret (key, token, password, or connection string). Please remove it — a note with a detected secret can’t be published.
Thanks — that helps. Published notes appear after a quick review.
Trending errors this week
The error guides other engineers are actually reading right now.
- 1mount: wrong fs type, bad option, bad superblock
- 2Docker 'failed to set up container networking': Fix the Bridge and IP Pool
- 3Docker 'failed to create shim task': How to Fix the containerd Runtime Error
- 4Transport endpoint is not connected
- 5modprobe: FATAL: Module not found
- 6mount: wrong fs type, bad option, bad superblock
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.