{"record":{"id":"ff007913ee75892c","repo":"hashicorp/terraform","slug":"registry-response-includes-invalid-sha256-hash-q","errorCode":null,"errorMessage":"registry response includes invalid SHA256 hash %q: %s","messagePattern":"registry response includes invalid SHA256 hash %q: (.+?)","errorType":"validation","errorClass":"ErrQueryFailed","httpStatus":null,"severity":"error","filePath":"internal/getproviders/registry_client.go","lineNumber":308,"sourceCode":"\t}\n\n\tret := PackageMeta{\n\t\tProvider:         provider,\n\t\tVersion:          version,\n\t\tProtocolVersions: protoVersions,\n\t\tTargetPlatform: Platform{\n\t\t\tOS:   body.OS,\n\t\t\tArch: body.Arch,\n\t\t},\n\t\tFilename: body.Filename,\n\t\tLocation: PackageHTTPURL(downloadURL.String()),\n\t\t// \"Authentication\" is populated below\n\t}\n\n\tif len(body.SHA256Sum) != sha256.Size*2 { // *2 because it's hex-encoded\n\t\treturn PackageMeta{}, c.errQueryFailed(\n\t\t\tprovider,\n\t\t\tfmt.Errorf(\"registry response includes invalid SHA256 hash %q: %s\", body.SHA256Sum, err),\n\t\t)\n\t}\n\n\tvar checksum [sha256.Size]byte\n\t_, err = hex.Decode(checksum[:], []byte(body.SHA256Sum))\n\tif err != nil {\n\t\treturn PackageMeta{}, c.errQueryFailed(\n\t\t\tprovider,\n\t\t\tfmt.Errorf(\"registry response includes invalid SHA256 hash %q: %s\", body.SHA256Sum, err),\n\t\t)\n\t}\n\n\tshasumsURL, err := url.Parse(body.SHA256SumsURL)\n\tif err != nil {\n\t\treturn PackageMeta{}, fmt.Errorf(\"registry response includes invalid SHASUMS URL: %s\", err)\n\t}\n\tshasumsURL = resp.Request.URL.ResolveReference(shasumsURL)\n\tif shasumsURL.Scheme != \"http\" && shasumsURL.Scheme != \"https\" {","sourceCodeStart":290,"sourceCodeEnd":326,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/getproviders/registry_client.go#L290-L326","documentation":"PackageMeta checks that the shasum field is exactly 64 hex characters (sha256.Size*2). If the length differs, the value cannot be a SHA-256 digest and the package is rejected via errQueryFailed (ErrQueryFailed). Note the message echoes err which at this branch is whatever prior error lingered, but the real cause is the wrong length.","triggerScenarios":"Registry response's shasum field is not 64 characters: a raw binary hash, a base64 digest, a truncated/extra-long string, or empty.","commonSituations":"Custom registry stored the digest in base64 instead of hex; registry emits sha1 (40 chars) or sha512 (128 chars); field accidentally includes a filename prefix like in a SHASUMS line; empty field when the registry lacks checksums.","solutions":["Ensure the registry emits shasum as a lowercase hex SHA-256 digest of exactly 64 chars.","If the registry only has another hash, compute/store the SHA-256 of the archive.","Strip any leading filename or whitespace from the field."],"exampleFix":"// before\n{\"shasum\":\"\"}\n// after\n{\"shasum\":\"9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08\"}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"func isRegistryShasumLengthErr(err error) bool {\n    var qf getproviders.ErrQueryFailed\n    if errors.As(err, &qf) {\n        return strings.Contains(qf.Wrapped.Error(), \"invalid SHA256 hash\")\n    }\n    return false\n}","tryCatchPattern":"meta, err := client.PackageMeta(ctx, provider, ver, plat)\nif err != nil {\n    var qf getproviders.ErrQueryFailed\n    if errors.As(err, &qf) && strings.Contains(qf.Wrapped.Error(), \"invalid SHA256 hash\") {\n        // registry shasum is malformed; surface to registry maintainer\n    }\n    return err\n}","preventionTips":["Registries must emit shasum as a 64-char lowercase hex SHA-256 digest.","Automate digest computation at publish time rather than copying by hand.","Add a publish-time unit test asserting len(shasum)==64."],"tags":["terraform","registry","sha256","checksum","provider-install"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T20:17:04.800Z"}