hashicorp/terraform · error

provider : required by this configuration but no version is…

Error message

provider %s: required by this configuration but no version is selected

What it means

During dependency selection verification, a provider required by the configuration has no corresponding entry in the dependency lock file (.terraform.lock.hcl). This means terraform init has not been run (or not re-run after adding a new provider requirement), so no version has been selected and locked for that provider.

Solutions

  1. Run terraform init to resolve and lock the missing provider.
  2. Verify the provider source address in required_providers matches exactly (e.g., hashicorp/aws vs registry.terraform.io/hashicorp/aws).
  3. Ensure .terraform.lock.hcl is committed to version control and not gitignored.
  4. If the provider was recently added, confirm the module referencing it is correctly referenced in the configuration.

Example fix

# before — new provider added but not initialized
required_providers {
  google = {
    source  = "hashicorp/google"
    version = "~> 4.0"
  }
}
# running `terraform plan` directly → error

# after — initialize first
terraform init
terraform plan
Defensive patterns

Strategy: validation

Validate before calling

// Check that every required provider has a lock entry before plan
// Shell pre-check:
//   terraform providers lock -platform=linux_amd64
// Or simply always run terraform init after changing required_providers.

// Go-side (if embedding Terraform):
func ensureProvidersLocked(workingDir string) error {
    cmd := exec.Command("terraform", "init", "-input=false", "-lockfile=readonly")
    cmd.Dir = workingDir
    return cmd.Run()
}

Prevention

When it happens

Trigger: A required_providers entry exists in the config (directly or via a module) but .terraform.lock.hcl has no provider block for that source address. Occurs after adding a new provider to the config without running terraform init, or after deleting the lock file, or after pulling a module that introduces a new provider dependency.

Common situations: Developer adds a new provider block to main.tf and runs terraform plan without terraform init. Team member clones the repo but the lock file is gitignored or was deleted. A module update pulls in a transitive provider dependency not in the lock file. Lock file was manually edited and the entry was removed.

Related errors


AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11). Data as JSON: /api/errors/fe89650ff7c8a873. Report an issue: GitHub.

Appendix: source

Thrown at internal/configs/config.go:293

		if !depsfile.ProviderIsLockable(providerAddr) {
			continue // disregard builtin providers, and such
		}
		if depLocks != nil && depLocks.ProviderIsOverridden(providerAddr) {
			// The "overridden" case is for unusual special situations like
			// dev overrides, so we'll explicitly note it in the logs just in
			// case we see bug reports with these active and it helps us
			// understand why we ended up using the "wrong" plugin.
			log.Printf("[DEBUG] Config.VerifyDependencySelections: skipping %s because it's overridden by a special configuration setting", providerAddr)
			continue
		}

		var lock *depsfile.ProviderLock
		if depLocks != nil { // Should always be true in main code, but unfortunately sometimes not true in old tests that don't fill out arguments completely
			lock = depLocks.Provider(providerAddr)
		}
		if lock == nil {
			log.Printf("[TRACE] Config.VerifyDependencySelections: provider %s has no lock file entry to satisfy %q", providerAddr, providerreqs.VersionConstraintsString(constraints))
			errs = append(errs, fmt.Errorf("provider %s: required by this configuration but no version is selected", providerAddr))
			continue
		}

		selectedVersion := lock.Version()
		allowedVersions := providerreqs.MeetingConstraints(constraints)
		log.Printf("[TRACE] Config.VerifyDependencySelections: provider %s has %s to satisfy %q", providerAddr, selectedVersion.String(), providerreqs.VersionConstraintsString(constraints))
		if !allowedVersions.Has(selectedVersion) {
			// The most likely cause of this is that the author of a module
			// has changed its constraints, but this could also happen in
			// some other unusual situations, such as the user directly
			// editing the lock file to record something invalid. We'll
			// distinguish those cases here in order to avoid the more
			// specific error message potentially being a red herring in
			// the edge-cases.
			currentConstraints := providerreqs.VersionConstraintsString(constraints)
			lockedConstraints := providerreqs.VersionConstraintsString(lock.VersionConstraints())
			switch {
			case currentConstraints != lockedConstraints:

View on GitHub (pinned to d32a084675)