hashicorp/terraform · error
provider : locked version selection doesn't match the…
Error message
provider %s: locked version selection %s doesn't match the updated version constraints %q
What it means
The locked version of a provider does not satisfy the configuration's version constraints, AND the current constraints differ from the constraints recorded in the lock file. This means the module author (or user) updated the version constraint in required_providers but did not run terraform init --upgrade to re-resolve. The lock file is stale relative to the changed requirement.
Solutions
- Run terraform init --upgrade to re-resolve providers against the updated constraints and refresh the lock file.
- If you intentionally want to keep the old version, revert the version constraint change in required_providers.
- After upgrading, commit the updated .terraform.lock.hcl to version control.
- Verify the new constraint is satisfiable: check the registry for available versions matching the constraint.
Example fix
# before — constraint changed but lock file not updated
required_providers {
aws = { version = "~> 4.0" } # was ~> 3.0, lock still says 3.x
}
terraform plan # → error
# after — re-resolve
terraform init --upgrade
terraform plan Defensive patterns
Strategy: validation
Validate before calling
// Verify lock file constraints match config constraints before plan
// Shell pre-check:
// terraform init -lockfile=readonly # fails if lock is stale
// If stale:
// terraform init -upgrade
// Go-side check (embedding):
func verifyLockFreshness(workingDir string) error {
cmd := exec.Command("terraform", "init", "-lockfile=readonly", "-input=false")
cmd.Dir = workingDir
return cmd.Run()
} Prevention
- Run terraform init -upgrade whenever you change version constraints in required_providers.
- Use terraform init -lockfile=readonly in CI to detect stale locks immediately.
- Commit the updated .terraform.lock.hcl after every constraint change.
- Review constraint changes in code review — they require a corresponding lock file update.
When it happens
Trigger: A required_providers version constraint was changed (e.g., from ~> 3.0 to ~> 4.0) but terraform init was not run with --upgrade. The locked version satisfies the old constraint but not the new one, and the lock file still records the old constraint string.
Common situations: Team upgrades a provider major version in the config and pushes without re-running init. A module is updated upstream with tighter constraints. User edits required_providers locally to test a newer version but forgets to update the lock. Lock file and config are out of sync after a git merge or rebase.
Related errors
- failed to determine the configuration's provider…
- provider : required by this configuration but no version is…
- provider : version constraints don't match the locked…
- address must be HTTP or HTTPS
- attempted to encode a malformed backend state file…
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/01d536550f940f41.
Report an issue: GitHub.
Appendix: source
Thrown at internal/configs/config.go:312
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:
errs = append(errs, fmt.Errorf("provider %s: locked version selection %s doesn't match the updated version constraints %q", providerAddr, selectedVersion.String(), currentConstraints))
default:
errs = append(errs, fmt.Errorf("provider %s: version constraints %q don't match the locked version selection %s", providerAddr, currentConstraints, selectedVersion.String()))
}
}
}
// Return multiple errors in an arbitrary-but-deterministic order.
sort.Slice(errs, func(i, j int) bool {
return errs[i].Error() < errs[j].Error()
})
return errs
}
// ProviderRequirements searches the full tree of modules under the receiver
// for both explicit and implicit dependencies on providers.
//
// The result is a full manifest of all of the providers that must be availableView on GitHub (pinned to d32a084675)