{"record":{"id":"b9a10c687eb66d2f","repo":"hashicorp/nomad","slug":"checksum-must-be-given-as-type-value-got-q","errorCode":null,"errorMessage":"checksum must be given as \"type:value\"; got %q","messagePattern":"checksum must be given as \"type:value\"; got %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/structs.go","lineNumber":9969,"sourceCode":"\t}\n\n\t// Job struct validation occurs before interpolation resolution can be effective.\n\t// Skip checking if checksum contain variable reference, and artifacts fetching will\n\t// eventually fail, if checksum is indeed invalid.\n\tif args.ContainsEnv(check) {\n\t\treturn nil\n\t}\n\n\tcheck = strings.TrimSpace(check)\n\tif check == \"\" {\n\t\treturn fmt.Errorf(\"checksum value cannot be empty\")\n\t}\n\n\t// Cut on the first colon only: a \"file:<url>\" checksum carries a URL\n\t// value that may itself contain colons (e.g. a port).\n\tchecksumType, checksumVal, ok := strings.Cut(check, \":\")\n\tif !ok {\n\t\treturn fmt.Errorf(`checksum must be given as \"type:value\"; got %q`, check)\n\t}\n\n\t// A \"file:<url>\" checksum tells go-getter to read the checksum from a\n\t// remote file rather than supplying a hex digest inline, so there is no\n\t// digest to validate here; the getter resolves it at fetch time.\n\tif checksumType == \"file\" {\n\t\treturn nil\n\t}\n\n\tchecksumBytes, err := hex.DecodeString(checksumVal)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"invalid checksum: %v\", err)\n\t}\n\n\texpectedLength := 0\n\tswitch checksumType {\n\tcase \"md5\":\n\t\tif fips140.Enabled() {","sourceCodeStart":9951,"sourceCodeEnd":9987,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/structs.go#L9951-L9987","documentation":"Inline artifact checksums must be formatted as \"type:value\", e.g. \"sha256:abcd...\". The validator splits on the first colon only (so URL values with colons are fine) and errors if no colon is present, meaning the type and value cannot be distinguished.","triggerScenarios":"checksum = \"sha256abcd1234\" or a bare hex digest without the \"type:\" prefix passed to an artifact block's checksum field.","commonSituations":"Users pasting just the hex digest from a release page; converting from tools that take only a digest; docs examples omitting the prefix.","solutions":["Prefix the digest with its algorithm and a colon, e.g. \"sha256:<hex>\".","Use one of md5, sha1, sha256, sha512 as the type (or \"file:<url>\" for remote checksum files).","Regenerate the checksum with a command that prints the prefixed form you can copy."],"exampleFix":"// before\nchecksum = \"3b5d2f...\"\n// after\nchecksum = \"sha256:3b5d2f...\"","handlingStrategy":"validation","validationCode":"_, val, ok := strings.Cut(checksum, \":\")\nif !ok { return fmt.Errorf(\"checksum %q must be type:value\", checksum) }\nif !validTypes[strings.Cut(checksum, \":\")[0]] { return errors.New(\"unsupported type\") }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always write checksum as \"<algo>:<hex>\"","Copy checksum lines from sha256sum output and prepend the type","Add a pre-submit lint rule requiring a colon in checksum"],"tags":["nomad","checksum","format","artifact"],"backgroundTag":"invalid-checksum-format","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}