hashicorp/terraform · error
provider package doesn't match the expected checksum
Error message
provider package doesn't match the expected checksum %q
What it means
Thrown by packageHashAuthentication.AuthenticatePackage when there is exactly one RequiredHash and the computed package hash does not match it. This is the single-hash mismatch path at package_authentication.go:258-259; the printed %q is the expected hash string. A mismatch means the staged package bytes differ from what the lock file/registry declared — corruption, tampering, or a wrong/mismatched package.
Solutions
- Delete the cached package and the affected lock-file hashes, then re-run init -upgrade to fetch a fresh, matching package and hash.
- Confirm the lock file's version constraint and hashes correspond to the same provider release (mismatched version+hash is a common cause).
- Verify the registry/mirror is serving the correct, current checksum for that version+platform.
- If the mismatch is unexpected on an official provider, treat it as possible tampering — re-download from the origin registry over a trusted network.
Defensive patterns
Strategy: try-catch
Try / catch
result, err := auth.AuthenticatePackage(loc)
if err != nil && strings.Contains(err.Error(), "doesn't match the expected checksum") {
// single-hash mismatch: do not weaken verification; re-download fresh
return result, fmt.Errorf("checksum mismatch (possible tampering or stale cache): %w", err)
} Prevention
- Never disable checksum verification to work around a mismatch.
- Regenerate the lock file after provider upgrades.
- Investigate persistent mismatches as possible tampering.
When it happens
Trigger: AuthenticatePackage with len(RequiredHashes)==1 where PackageMatchesAnyHash returned false. Typical with a network mirror returning a single hash; a manually replaced plugin binary; a lock file hash from a different provider version.
Common situations: A provider version was re-published/repacked so the bytes changed but the lock file pins the old hash; someone copied a different provider binary into the cache; a CI cache of .terraform/providers holds a stale package from a prior version; a network mirror served a wrong hash.
Related errors
- provider package doesn't match the any of the expected…
- archive has incorrect checksum
- this version of Terraform does not support any of the…
- checksum list has unexpected SHA-256 hash
- failed to verify provider package checksums
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/e5618d09ab616c1a.
Report an issue: GitHub.
Appendix: source
Thrown at internal/getproviders/package_authentication.go:259
func (a packageHashAuthentication) AuthenticatePackage(localLocation PackageLocation) (*PackageAuthenticationResult, error) {
if len(a.RequiredHashes) == 0 {
// Indicates that none of the hashes given to
// NewPackageHashAuthentication were considered to be usable by this
// version of Terraform.
return nil, fmt.Errorf("this version of Terraform does not support any of the checksum formats given for this provider")
}
matches, err := PackageMatchesAnyHash(localLocation, a.RequiredHashes)
if err != nil {
return nil, fmt.Errorf("failed to verify provider package checksums: %s", err)
}
if matches {
return &PackageAuthenticationResult{result: verifiedChecksum}, nil
}
if len(a.RequiredHashes) == 1 {
return nil, fmt.Errorf("provider package doesn't match the expected checksum %q", a.RequiredHashes[0].String())
}
// It's non-ideal that this doesn't actually list the expected checksums,
// but in the many-checksum case the message would get pretty unweildy.
// In practice today we typically use this authenticator only with a
// single hash returned from a network mirror, so the better message
// above will prevail in that case. Maybe we'll improve on this somehow
// if the future introduction of a new hash scheme causes there to more
// commonly be multiple hashes.
return nil, fmt.Errorf("provider package doesn't match the any of the expected checksums")
}
func (a packageHashAuthentication) AcceptableHashes() []Hash {
// In this case we include even hashes the current version of Terraform
// doesn't prefer, because this result is used for building a lock file
// and so it's helpful to include older hash formats that other Terraform
// versions might need in order to do authentication successfully.
return a.AllHashes
}View on GitHub (pinned to d32a084675)