hashicorp/terraform · error
provider package doesn't match the expected checksum %q
Error message
provider package doesn't match the expected checksum %q
What it means
Single-hash mismatch from packageHashAuthentication.AuthenticatePackage. Exactly one RequiredHash was acceptable to this binary, the package was successfully hashed, but PackageMatchesAnyHash returned false. The '%q' is the one expected hash (its full 'h1:'/'zh:' string). This is an integrity failure: the bytes on disk do not match the locked/declared checksum.
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 c9def3e214)
Solutions
- Confirm the expected hash in the error matches the lock file / mirror; if the mirror's hash is wrong, update or replace the mirror.
- Re-download the package: purge .terraform/providers and the plugin cache, then 'terraform init'.
- If you control the mirror, recompute and republish the correct 'h1:' hash for the served artifact.
- Verify the version string is not ambiguous (e.g. a provider re-released at the same version with different bytes); pin to a specific build or update the lock entry to match the current artifact.
Example fix
// before: lock pinned to a stale hash hashes = ["h1:OLDHASH..."] // after: regenerate the lock against the real artifact $ rm .terraform.lock.hcl && terraform init
Defensive patterns
Strategy: validation
Validate before calling
// Recompute the hash locally and compare to the lock entry before trusting a mirror.
computed, err := getproviders.PackageHashV1(loc)
if err != nil { return err }
if computed != expected { return fmt.Errorf("staged package hash %s != expected %s", computed, expected) } Try / catch
_, err := auth.AuthenticatePackage(loc)
if err != nil {
if strings.Contains(err.Error(), "doesn't match the expected checksum") {
// integrity drift: do NOT silently proceed. Purge cache + re-init or fail.
}
return err
} Prevention
- Pin provider versions explicitly so the same build is fetched each time.
- Use the official registry as the source of truth for hashes; only trust mirrors that mirror it byte-for-byte.
- Investigate every single-hash mismatch rather than relaxing the check.
When it happens
Trigger: len(a.RequiredHashes)==1 and PackageMatchesAnyHash returns (false, nil) at line 255, reaching line 259. In practice this is the network-mirror path, which typically supplies a single hash. The package downloaded fine but its computed hash differs from the mirror-provided one.
Common situations: A filesystem mirror whose published hash is stale (points at an older build of the same version). A corrupt or partially-overwritten download that produced a valid but wrong archive. A man-in-the-middle or CDN serving a tampered package. Lock file pinned to a hash that no longer matches the registry artifact after a republish.
Related errors
- provider package doesn't match the any of the expected check
- this version of Terraform does not support any of the checks
- archive has incorrect checksum %s (expected %s)
- ErrChecksumDoesNotMatch
- Failed obtain the in-use version of provider %s (%q) used wi
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/e5618d09ab616c1a.
Report an issue: GitHub.