{"record":{"id":"e5618d09ab616c1a","repo":"hashicorp/terraform","slug":"provider-package-doesn-t-match-the-expected-checks","errorCode":null,"errorMessage":"provider package doesn't match the expected checksum %q","messagePattern":"provider package doesn't match the expected checksum %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/getproviders/package_authentication.go","lineNumber":259,"sourceCode":"\nfunc (a packageHashAuthentication) AuthenticatePackage(localLocation PackageLocation) (*PackageAuthenticationResult, error) {\n\tif len(a.RequiredHashes) == 0 {\n\t\t// Indicates that none of the hashes given to\n\t\t// NewPackageHashAuthentication were considered to be usable by this\n\t\t// version of Terraform.\n\t\treturn nil, fmt.Errorf(\"this version of Terraform does not support any of the checksum formats given for this provider\")\n\t}\n\n\tmatches, err := PackageMatchesAnyHash(localLocation, a.RequiredHashes)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to verify provider package checksums: %s\", err)\n\t}\n\n\tif matches {\n\t\treturn &PackageAuthenticationResult{result: verifiedChecksum}, nil\n\t}\n\tif len(a.RequiredHashes) == 1 {\n\t\treturn nil, fmt.Errorf(\"provider package doesn't match the expected checksum %q\", a.RequiredHashes[0].String())\n\t}\n\t// It's non-ideal that this doesn't actually list the expected checksums,\n\t// but in the many-checksum case the message would get pretty unweildy.\n\t// In practice today we typically use this authenticator only with a\n\t// single hash returned from a network mirror, so the better message\n\t// above will prevail in that case. Maybe we'll improve on this somehow\n\t// if the future introduction of a new hash scheme causes there to more\n\t// commonly be multiple hashes.\n\treturn nil, fmt.Errorf(\"provider package doesn't match the any of the expected checksums\")\n}\n\nfunc (a packageHashAuthentication) AcceptableHashes() []Hash {\n\t// In this case we include even hashes the current version of Terraform\n\t// doesn't prefer, because this result is used for building a lock file\n\t// and so it's helpful to include older hash formats that other Terraform\n\t// versions might need in order to do authentication successfully.\n\treturn a.AllHashes\n}","sourceCodeStart":241,"sourceCodeEnd":277,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/getproviders/package_authentication.go#L241-L277","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: lock pinned to a stale hash\nhashes = [\"h1:OLDHASH...\"]\n// after: regenerate the lock against the real artifact\n$ rm .terraform.lock.hcl && terraform init","handlingStrategy":"validation","validationCode":"// Recompute the hash locally and compare to the lock entry before trusting a mirror.\ncomputed, err := getproviders.PackageHashV1(loc)\nif err != nil { return err }\nif computed != expected { return fmt.Errorf(\"staged package hash %s != expected %s\", computed, expected) }","typeGuard":null,"tryCatchPattern":"_, err := auth.AuthenticatePackage(loc)\nif err != nil {\n    if strings.Contains(err.Error(), \"doesn't match the expected checksum\") {\n        // integrity drift: do NOT silently proceed. Purge cache + re-init or fail.\n    }\n    return err\n}","preventionTips":["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."],"tags":["checksum","integrity","provider","mirror","lock-file"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T21:17:07.882Z"}