{"record":{"id":"6d6c929da1d85d82","repo":"hashicorp/terraform","slug":"downloaded-archive-does-not-match-the-release-chec","errorCode":null,"errorMessage":"downloaded archive does not match the release checksum","messagePattern":"downloaded archive does not match the release checksum","errorType":"validation","errorClass":"ErrChecksumDoesNotMatch","httpStatus":null,"severity":"critical","filePath":"internal/releaseauth/checksum.go","lineNumber":28,"sourceCode":"\t\"fmt\"\n\t\"io\"\n\t\"log\"\n\t\"os\"\n)\n\n// ChecksumAuthentication is an archive Authenticator that ensures a given file\n// matches a SHA-256 checksum. It is important to verify the authenticity of the\n// given checksum prior to using this Authenticator.\ntype ChecksumAuthentication struct {\n\tAuthenticator\n\n\texpected        SHA256Hash\n\tarchiveLocation string\n}\n\n// ErrChecksumDoesNotMatch is the error returned when the archive checksum does\n// not match the given checksum.\nvar ErrChecksumDoesNotMatch = errors.New(\"downloaded archive does not match the release checksum\")\n\n// NewChecksumAuthentication creates an instance of ChecksumAuthentication with the given\n// checksum and file location.\nfunc NewChecksumAuthentication(expected SHA256Hash, archiveLocation string) *ChecksumAuthentication {\n\treturn &ChecksumAuthentication{\n\t\texpected:        expected,\n\t\tarchiveLocation: archiveLocation,\n\t}\n}\n\nfunc (a ChecksumAuthentication) Authenticate() error {\n\tf, err := os.Open(a.archiveLocation)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to open downloaded archive: %w\", err)\n\t}\n\tdefer f.Close()\n\n\th := sha256.New()","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/releaseauth/checksum.go#L10-L46","documentation":"ErrChecksumDoesNotMatch is returned by ChecksumAuthentication.Authenticate after SHA-256 hashing the on-disk archive and finding the digest does not equal the expected hash supplied at construction. The comment on the type stresses that the expected checksum itself must already be trusted (typically because it came from a signature-verified SHA256SUMS file) — this authenticator only proves the bytes match, not that the checksum is authentic.","triggerScenarios":"NewChecksumAuthentication(expected, path).Authenticate() reads archiveLocation, hashes it with SHA-256, and at checksum.go:54 compares gotHash to a.expected[:]; on mismatch it returns ErrChecksumDoesNotMatch.","commonSituations":"Truncated or corrupted download (network error mid-transfer); tampered/ MitM-modified archive; expected hash taken from the wrong release's SHA256SUMS; partial write left on disk from a previous failed download.","solutions":["Re-download the archive cleanly (delete the partial file first) and re-authenticate.","Confirm the expected SHA256Hash was extracted from the correct release's SHA256SUMS entry for this exact filename.","If the checksum in SHA256SUMS is genuinely wrong, the release is broken — report it; do not weaken verification.","Verify the SHA256SUMS file itself was signature-authenticated (SignatureAuthentication) before trusting its contents."],"exampleFix":"// before\nauth := releaseauth.NewChecksumAuthentication(expectedHash, archivePath)\nif err := auth.Authenticate(); err != nil {\n    return err // re-using a possibly-corrupt file\n}\n\n// after — remove partial then re-download before authenticating\n_ = os.Remove(archivePath)\nif err := redownload(archivePath); err != nil {\n    return err\n}\nauth := releaseauth.NewChecksumAuthentication(expectedHash, archivePath)\nif err := auth.Authenticate(); err != nil {\n    return fmt.Errorf(\"archive checksum mismatch after fresh download: %w\", err)\n}","handlingStrategy":"try-catch","validationCode":"// Hash before authenticating to give a clearer error\nf, _ := os.Open(archivePath)\nh := sha256.New()\nio.Copy(h, f)\nactual := hex.EncodeToString(h.Sum(nil))\nexpected := hex.EncodeToString(expectedHash[:])\nif actual != expected {\n    log.Printf(\"expected %s got %s\", expected, actual)\n}","typeGuard":"func isChecksumMismatch(err error) bool {\n    return errors.Is(err, releaseauth.ErrChecksumDoesNotMatch)\n}","tryCatchPattern":"err := releaseauth.NewChecksumAuthentication(expected, path).Authenticate()\nif errors.Is(err, releaseauth.ErrChecksumDoesNotMatch) {\n    _ = os.Remove(path) // discard corrupt archive\n    return redownloadAndAuthenticate(path, expected)\n}","preventionTips":["Always authenticate the SHA256SUMS file (signature) before trusting its checksums.","Delete partial/corrupt downloads rather than re-authenticating in place.","Log expected-vs-actual hashes to make mismatches easy to diagnose.","Never weaken or skip checksum verification, even on retry."],"tags":["security","checksum","sha256","integrity","terraform"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}