{"record":{"id":"039e8eaf0e2488db","repo":"hashicorp/packer","slug":"invalid-sha256-checksum-format-for-s-in-sha256sum","errorCode":null,"errorMessage":"invalid SHA256 checksum format for %s in SHA256SUMS","messagePattern":"invalid SHA256 checksum format for (.+?) in SHA256SUMS","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"provisioner/hcp-sbom/packer_release_fetch.go","lineNumber":190,"sourceCode":"func isValidSHA256Hex(s string) bool {\n\tif len(s) != 64 {\n\t\treturn false\n\t}\n\t_, err := hex.DecodeString(s)\n\treturn err == nil\n}\n\nfunc expectedZipSHA256FromSums(sumsContent, fileName string) (string, error) {\n\tfor _, line := range strings.Split(sumsContent, \"\\n\") {\n\t\tfields := strings.Fields(strings.TrimSpace(line))\n\t\tif len(fields) < 2 {\n\t\t\tcontinue\n\t\t}\n\t\tcandidateFileName := strings.TrimPrefix(fields[len(fields)-1], \"*\")\n\t\tif candidateFileName == fileName {\n\t\t\thash := strings.ToLower(fields[0])\n\t\t\tif !isValidSHA256Hex(hash) {\n\t\t\t\treturn \"\", fmt.Errorf(\"invalid SHA256 checksum format for %s in SHA256SUMS\", fileName)\n\t\t\t}\n\t\t\treturn hash, nil\n\t\t}\n\t}\n\treturn \"\", fmt.Errorf(\"checksum for %s not found in SHA256SUMS\", fileName)\n}\n\nfunc fileSHA256(path string) (string, error) {\n\tf, err := os.Open(path)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to open %s for hashing: %w\", path, err)\n\t}\n\tdefer func() { _ = f.Close() }()\n\n\th := sha256.New()\n\tif _, err := io.Copy(h, f); err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed hashing %s: %w\", path, err)\n\t}","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/hashicorp/packer/blob/eb36e3c3e48a036f3e8cc94087636ee72e1303c9/provisioner/hcp-sbom/packer_release_fetch.go#L172-L208","documentation":"expectedZipSHA256FromSums parses a SHA256SUMS file line by line. When it finds a line whose filename matches the target zip, it validates the first field is a valid 64-character lowercase hex SHA-256 digest via isValidSHA256Hex. If the matched line's hash field is not valid hex of length 64, it refuses to return it and throws this error to prevent verifying against a corrupt or malformed checksum.","triggerScenarios":"The SHA256SUMS content contains a line ending with the exact zip filename, but fields[0] is not 64 hex characters — e.g. a truncated line, an MD5/other digest format, 'sha256 <hash>' with extra tokens shifting parsing, a binary/BOM-corrupted file, or a hand-edited checksums file.","commonSituations":"Serving SHA256SUMS from a custom/internal mirror generated with the wrong tool or checksum algorithm; a proxy mangling the file (encoding/BOM insertion); a stub test server with placeholder checksum values like 'xxx'; lines in an unexpected format such as '<hash>  *file' with extra whitespace tokens.","solutions":["Inspect the SHA256SUMS file (curl <shaSumsURL>) and check the line for the target zip; verify the first field is exactly 64 hex characters.","Regenerate the checksums file on your mirror with sha256sum (format: '<64-hex-hash>  <filename>').","Ensure no proxy/transform is modifying the file (check for BOM or HTML error pages served with 200).","Confirm the filename matched is the intended one — a coincidental match with a line in another format will trip this validation."],"exampleFix":"// before: mirror serving malformed sums\n// abc123  packer_1.11.0_linux_amd64.zip\n\n// after: regenerate with sha256sum on the mirror\n// sha256sum packer_1.11.0_linux_amd64.zip >> packer_1.11.0_SHA256SUMS\n// -> a1b2c3...64hex...  packer_1.11.0_linux_amd64.zip","handlingStrategy":"validation","validationCode":"func validateSumsLine(line, fileName string) error {\n    fields := strings.Fields(strings.TrimSpace(line))\n    if len(fields) < 2 || strings.TrimPrefix(fields[len(fields)-1], \"*\") != fileName {\n        return nil\n    }\n    h := strings.ToLower(fields[0])\n    if len(h) != 64 {\n        return fmt.Errorf(\"hash field for %s is %d chars, want 64\", fileName, len(h))\n    }\n    if _, err := hex.DecodeString(h); err != nil {\n        return fmt.Errorf(\"hash field for %s is not valid hex: %v\", fileName, err)\n    }\n    return nil\n}","typeGuard":"func isValidSHA256Hex(s string) bool {\n    if len(s) != 64 {\n        return false\n    }\n    _, err := hex.DecodeString(s)\n    return err == nil\n}","tryCatchPattern":"expectedSHA, err := expectedZipSHA256FromSums(sumsContent, fileName)\nif err != nil {\n    if strings.Contains(err.Error(), \"invalid SHA256 checksum format\") {\n        log.Printf(\"SHA256SUMS content corrupted for %s, refusing verify\", fileName)\n        // fail fast: never verify against a malformed checksum\n    }\n    return err\n}","preventionTips":["Generate SHA256SUMS with sha256sum so the format is '<64-hex>  <filename>'.","Serve checksum files as plain text (no BOM, no HTML error pages, no content transformation).","Add a CI check that validates every line of your mirror's SHA256SUMS with a 64-hex regex.","Never hand-edit checksum files."],"tags":["checksum","validation","sha256","go"],"backgroundTag":"invalid-checksum-format","analyzedSha":"eb36e3c3e48a036f3e8cc94087636ee72e1303c9","analyzedAt":"2026-09-05T13:20:43.127Z","contentChangedAt":"2026-09-05T13:20:43.127Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}