The Error
Error: Provider configuration not present
To work with module.networking.aws_vpc.main its original provider
configuration at module.networking.provider["registry.terraform.io/hashicorp/aws"].eu_west
must be available in the state, but is no longer present.
What you're looking at is a state mismatch. Terraform found resources in terraform.tfstate that were created with a provider alias โ but that alias is gone from your current config. Without it, Terraform can't plan, apply, or destroy those resources. The underlying AWS infrastructure may be perfectly fine. Terraform is just stuck without its handle.
Why This Happens
Every resource in terraform.tfstate carries a provider fingerprint. Use a provider alias inside a module and that alias gets baked into the resource's identity. Rename it, remove it, or forget to pass it โ Terraform loses the handle it needs to manage those resources.
The most common triggers:
- You removed or commented out the
providersblock in a module call - You renamed a provider alias (e.g.,
aws.secondaryโaws.eu) - You deleted a
providerblock in the root module - You removed the entire module block without destroying its resources first
- A teammate refactored the providers map and didn't update all module calls
Root Cause: How Provider Aliases Work in Modules
Here's the classic multi-region pattern that triggers this error:
# root/main.tf โ two AWS provider configurations
provider "aws" {
region = "us-east-1"
}
provider "aws" {
alias = "eu_west" # alias name matters
region = "eu-west-1"
}
# Module call โ passes the aliased provider explicitly
module "networking" {
source = "./modules/networking"
providers = {
aws = aws.eu_west
}
}
Inside the child module, resources use this aliased provider:
# modules/networking/main.tf
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
}
Terraform records that resource in state as tied to module.networking.provider["registry.terraform.io/hashicorp/aws"].eu_west. Remove the providers map or rename eu_west, and Terraform can't locate that original configuration โ hence the error.
Fix 1: Restore the Provider Alias in the Module Call
Nine times out of ten, someone removed or changed the providers block by accident. Putting it back exactly as it was when those resources were first created fixes the error immediately.
# Step 1: Check what alias the state expects
terraform state show module.networking.aws_vpc.main
Find the provider field in the output. It shows the exact alias path Terraform expects:
provider = "provider[\"registry.terraform.io/hashicorp/aws\"].eu_west"
# Step 2: Make sure your root module has a matching alias
provider "aws" {
alias = "eu_west" # Must match the name from state exactly
region = "eu-west-1"
}
# Step 3: Pass it in the module call
module "networking" {
source = "./modules/networking"
providers = {
aws = aws.eu_west
}
}
One more hardening step โ declare configuration_aliases in the child module. This turns a missing providers map into a plan-time error instead of a silent footgun:
# modules/networking/versions.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
configuration_aliases = [aws]
}
}
}
# Step 4: Verify the fix
terraform plan
No provider error and only expected changes in the plan? You're done.
Fix 2: You Need to Rename the Alias
Renaming an alias isn't a cosmetic change โ Terraform treats it as a completely different provider. Resources in state still point to the old name, so you can't just swap aws.eu_west for aws.eu and move on.
Option A โ Destroy resources with the old alias, then recreate with the new one:
# 1. Temporarily revert the alias to the old name
provider "aws" {
alias = "eu_west" # Old name
region = "eu-west-1"
}
module "networking" {
source = "./modules/networking"
providers = { aws = aws.eu_west }
}
# 2. Destroy the resources cleanly
terraform destroy -target=module.networking
# 3. Now rename the alias and update the module call
provider "aws" {
alias = "eu" # New name
region = "eu-west-1"
}
module "networking" {
source = "./modules/networking"
providers = { aws = aws.eu }
}
# 4. Recreate
terraform apply
Option B โ Remove from state and reimport (for production resources you cannot recreate):
# 1. Remove the resource from Terraform state
# (does NOT delete the actual cloud resource)
terraform state rm module.networking.aws_vpc.main
# 2. Rename the alias in your .tf files
# 3. Import the existing resource under the new provider path
terraform import module.networking.aws_vpc.main vpc-0abc123def456789ab
Run terraform state list first to get the full list of resources tied to the old alias. Then repeat the state rm + import cycle for each one.
Fix 3: You Want to Remove the Module Entirely
Deleting a module block without destroying its resources first is exactly how you land in this error. Terraform needs the provider configuration to plan the destroy operation. Pull the block, and you've taken that away.
# Wrong approach โ leads directly to the 'Provider configuration not present' error:
# 1. Delete the module block
# 2. Run terraform apply โ error here
# Correct approach:
# 1. Keep the module block in place
terraform destroy -target=module.networking
# 2. Only AFTER successful destroy, remove the module block from your .tf files
# 3. Run apply (should be a no-op)
terraform apply
Verification Steps
Before calling it done, run these three checks:
# 1. Plan should run without provider errors
terraform plan
# 2. Check the resource is still in state
terraform state list | grep module.networking
# 3. Confirm the provider path in state matches your alias
terraform state show module.networking.aws_vpc.main | grep provider
The last command should output something like:
provider = "provider[\"registry.terraform.io/hashicorp/aws\"].eu_west"
That alias name must match what you have in the root provider block. If it doesn't, you're not done yet.
Prevention
- Destroy before removing: Always run
terraform destroy -target=module.xxxbefore deleting a module block or retiring an alias. Removing config and running apply in one step will break things. - Declare
configuration_aliasesin child modules: Forces callers to pass a provider map explicitly. A missing map becomes a plan-time error, not a runtime surprise. - Treat alias renames as breaking changes: Update every module call that uses the alias in the same commit. Test the rename in a non-production workspace before touching main.
- Audit state before big refactors: Run
terraform state listbefore restructuring modules โ it shows exactly which resources are tied to which alias, so nothing gets stranded. - Separate state files per region: For complex multi-region setups, one Terraform root module per region sidesteps alias management almost entirely. More files, fewer alias headaches.
Working with YAML-based configs alongside Terraform โ like terragrunt.hcl or variable input files? ToolCraft's YAML โ JSON Converter catches indentation and formatting issues before terraform init does.

