TerraformTerraform

Error: Provider configuration not present

Terraform needs a provider configuration to destroy a resource whose provider block is gone, or a module is not receiving the aliased provider you think it is.

hard fix5 min read

the terraform error
Error: Provider configuration not present
To work with aws_instance.web its original provider configuration at provider["registry.terraform.io/hashicorp/aws"].eu_west_1 is required, but it has been removed. This occurs when a provider configuration is removed while objects created by that provider still exist in the state.

Error: Missing required provider configuration
The provider aws.replica is required but no configuration is present.

Do this first3 steps

Run these in order. Each one tells you what its output means before you change anything.

  1. 1

    Find which resources still reference the missing provider

    terraform state list | head -50

    The error names the provider address, including the alias after the dot. Every resource created through it still records that address in state, and Terraform needs the configuration back in order to destroy or refresh them.

  2. 2

    Put the provider block back temporarily so the destroy can run

    terraform plan -destroy

    Restoring the removed provider block lets Terraform reach the resources and remove them properly. Delete the block only after the resources are gone from state.

  3. 3

    For a module, confirm what it is actually receiving

    terraform providers

    The tree shows which provider configuration each module is given. A module declaring configuration_aliases must be passed the alias explicitly through a providers argument; inheritance does not cover aliases.

All 7 sections

Terraform records, for every resource in state, which provider configuration created it. If that configuration disappears from the code while the resource still exists, Terraform cannot refresh or destroy it and refuses to continue.

There are two quite different situations behind the same heading.

Situation 1: You deleted a provider block

To work with aws_instance.web its original provider configuration at
provider["registry.terraform.io/hashicorp/aws"].eu_west_1 is required,
but it has been removed.

The .eu_west_1 is an alias. Something like this was removed:

provider "aws" {
  alias  = "eu_west_1"
  region = "eu-west-1"
}

The resources it created are still in state and still exist in AWS. Terraform needs credentials and a region to talk to them, which is exactly what the block provided.

Put it back, destroy the resources properly, then remove it:

provider "aws" {
  alias  = "eu_west_1"
  region = "eu-west-1"
}
terraform plan -destroy -target='aws_instance.web'
terraform apply -destroy -target='aws_instance.web'
# now delete the provider block
terraform plan

Deleting real infrastructure and its provider block in one change is the mistake. Remove the resources first, apply, then remove the provider.

If the resources are already gone

Sometimes the infrastructure was deleted outside Terraform and only state remembers it. Then you want the state entries removed without touching anything:

terraform state list | grep aws_instance
terraform state rm 'aws_instance.web'

terraform state rm forgets the resource without destroying it. Take a state backup first, because this is not reversible in place:

terraform state pull > backup.tfstate

If the resources still exist and you state rm them, they become orphans: running, billing, and unmanaged. That is the failure mode to be careful about, and it is why restoring the provider block and destroying properly is the better path whenever the resources are real.

Situation 2: A module is not receiving an aliased provider

Error: Missing required provider configuration
The provider aws.replica is required but no configuration is present.

Modules inherit the default provider configuration automatically. They do not inherit aliased ones. A module that needs an alias must declare it and be given it explicitly.

In the module:

terraform {
  required_providers {
    aws = {
      source                = "hashicorp/aws"
      version               = ">= 5.0"
      configuration_aliases = [aws.replica]
    }
  }
}

resource "aws_s3_bucket" "replica" {
  provider = aws.replica
  bucket   = "acme-replica"
}

In the root:

provider "aws" {
  region = "eu-west-1"
}

provider "aws" {
  alias  = "replica"
  region = "us-east-1"
}

module "buckets" {
  source = "./modules/buckets"
  providers = {
    aws         = aws            # the default
    aws.replica = aws.replica    # the alias
  }
}

The providers map is required once the module declares configuration_aliases. Note that passing providers at all switches off inheritance, so if you map the alias you must map the default too, or the module loses it.

Check what a module is actually getting:

terraform providers

Provider blocks inside modules

A child module that declares its own provider block works and is discouraged, for exactly the reason this error exists: the module's callers cannot then remove or change it, and terraform destroy on a removed module fails because the provider went with it.

The pattern that avoids this is for modules to declare required_providers and receive configurations from the root. Only root modules should contain provider blocks. A count or for_each on a module whose provider is declared internally is rejected outright for the same reason.

After a refactor

Moving resources between modules changes their state addresses but not their provider references. If the target module has no matching provider configuration, this error appears during the move.

Prefer a moved block over terraform state mv, since it is reviewable and travels with the code:

moved {
  from = aws_s3_bucket.old
  to   = module.buckets.aws_s3_bucket.replica
}

Confirm the target module receives the provider the resource was created with before applying.

A checklist

  1. Read the provider address in the error, including anything after the dot.
  2. Alias present → a provider block with that alias was removed.
  3. Resources still real → restore the block, destroy them, then remove it.
  4. Resources already gone → terraform state pull > backup then terraform state rm.
  5. Never state rm a resource that still exists unless you intend to orphan it.
  6. Missing required provider configuration → a module needs an alias passed explicitly.
  7. Declare configuration_aliases in the module and map both default and alias in providers.
  8. Keep provider blocks in root modules only.

Frequently Asked Questions

Why does Terraform need the provider configuration to destroy something?

Because destroying a resource means calling the provider's API, and the provider configuration is what supplies the credentials, region and endpoint to call. State records which provider configuration created each resource precisely so Terraform can reach it again later. Remove the block and Terraform still knows the resource exists but has no way to talk to it, so rather than guess at a default that might point at the wrong account or region, it stops and tells you the configuration is missing.

What is the right order for removing a provider and its resources?

Remove the resources first and apply, then remove the provider block in a second change. Deleting both at once leaves state holding objects whose provider is gone, which is exactly this error. If you have already done it, restoring the provider block temporarily is the cleanest recovery: put it back, run a targeted destroy on the affected resources, confirm state is clean, and only then delete the block again.

Do modules inherit provider configurations automatically?

They inherit the default configuration, and not aliased ones. A module that needs an alias must declare it in required_providers with configuration_aliases, and the caller must pass it in the providers map. There is an important side effect: supplying a providers argument at all disables automatic inheritance for that module, so if you map an alias you must also map the default explicitly or the module will lose it.

When is terraform state rm the right answer?

Only when the real infrastructure is already gone and state is the only thing that still remembers it, or when you deliberately intend to stop managing a resource without destroying it. Running it on a resource that still exists orphans that resource: it keeps running, it keeps billing, and nothing manages it any more. Always take a backup with terraform state pull > backup.tfstate first, because the operation cannot be undone in place and recovering means pushing the backup back.

Should modules declare their own provider blocks?

No, as a rule. A provider block inside a child module cannot be overridden or removed by its callers, which makes the module impossible to use in a second region and makes terraform destroy fail once the module is removed, since the provider configuration disappears with it. Terraform also refuses to allow count or for_each on such a module. Declare required_providers in the module, accept configurations from the root, and keep provider blocks in root modules only.

Reference and practice

Learn the underlying concept

Other Terraform errors