{"record":{"id":"c8bad7fcbb79df7d","repo":"hasura/graphql-engine","slug":"sha256-value-s-is-not-valid-must-match-pattern","errorCode":null,"errorMessage":"`sha256` value %s is not valid, must match pattern %s","messagePattern":"`sha256` value (.+?) is not valid, must match pattern (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/plugins/util.go","lineNumber":87,"sourceCode":"\n\treturn true\n}\n\n// validatePlatform checks Platform for structural validity.\nfunc validatePlatform(p Platform) error {\n\tvar op errors.Op = \"plugins.validatePlatform\"\n\tif p.URI == \"\" {\n\t\treturn errors.E(op, \"`uri` has to be set\")\n\t}\n\n\tif p.Sha256 == \"\" {\n\t\treturn errors.E(op, \"`sha256` sum has to be set\")\n\t}\n\n\tif !isValidSHA256(p.Sha256) {\n\t\treturn errors.E(\n\t\t\top,\n\t\t\tfmt.Errorf(\n\t\t\t\t\"`sha256` value %s is not valid, must match pattern %s\",\n\t\t\t\tp.Sha256,\n\t\t\t\tsha256Pattern,\n\t\t\t),\n\t\t)\n\t}\n\n\tif p.Bin == \"\" {\n\t\treturn errors.E(op, \"`bin` has to be set\")\n\t}\n\n\terr := validateFiles(p.Files)\n\tif err != nil {\n\t\treturn errors.E(op, fmt.Errorf(\"`files` is invalid: %w\", err))\n\t}\n\n\treturn nil\n}","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/hasura/graphql-engine/blob/724551b9ae87845594ef0408cff0e50eb6c90dc5/cli/plugins/util.go#L69-L105","documentation":"validatePlatform requires the manifest's sha256 field to be a valid hex SHA-256 digest (64 hex characters matching sha256Pattern in cli/plugins/util.go). The sum is later used by download.NewSha256Verifier to authenticate the downloaded archive, so a malformed value is rejected up front.","triggerScenarios":"A platforms[] entry with a sha256 that is empty (but the earlier \"has to be set\" check passed to something invalid), shorter/longer than 64 chars, containing uppercase or non-hex characters, or a Base64-encoded digest instead of hex.","commonSituations":"Copy-pasting a truncated hash; pasting a Base64 checksum from a release page; including the leading filename part of `sha256sum` output (\"abc...  file.tar.gz\") instead of just the hex digest.","solutions":["Recompute the digest with sha256sum <archive> and paste ONLY the 64 lowercase hex characters.","Remove any whitespace, filename suffix, 'sha256:' prefix, or Base64 encoding from the value.","Verify length == 64 and all chars are [0-9a-f] before publishing the manifest."],"exampleFix":"// before\n\"sha256\": \"sha256:9f2a...\"\n\n// after\n\"sha256\": \"9f2a86e0aa2b6c3ed54eb0ec2b2d80d0e2c8e41b0d1c9c58e5a2e1ff8bf2a7f14\"","handlingStrategy":"validation","validationCode":"var sha256Re = regexp.MustCompile(`^[a-f0-9]{64}$`)\n\nfunc isValidSum(s string) bool { return sha256Re.MatchString(s) }","typeGuard":"func isHexSha256(s string) bool {\n\tif len(s) != 64 {\n\t\treturn false\n\t}\n\tfor _, c := range s {\n\t\tif !((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f')) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}","tryCatchPattern":null,"preventionTips":["Generate the field with `sha256sum file | cut -d' ' -f1`, never by hand.","Automate manifest generation from the release pipeline so sums are always fresh.","Reject uppercase/base64 digests in linting."],"tags":["plugins","validation","checksum","sha256","manifest"],"backgroundTag":"checksum-validation-failed","analyzedSha":"724551b9ae87845594ef0408cff0e50eb6c90dc5","analyzedAt":"2026-08-28T07:32:55.105Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}