{"record":{"id":"9fa97a7bde5fc0a8","repo":"hashicorp/terraform","slug":"hash-string-must-start-with-a-scheme-keyword-follo","errorCode":null,"errorMessage":"hash string must start with a scheme keyword followed by a colon","messagePattern":"hash string must start with a scheme keyword followed by a colon","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/getproviders/providerreqs/hash.go","lineNumber":48,"sourceCode":"\n// ParseHash parses the string representation of a Hash into a Hash value.\n//\n// A particular version of Terraform only supports a fixed set of hash schemes,\n// but this function intentionally allows unrecognized schemes so that we can\n// silently ignore other schemes that may be introduced in the future. For\n// that reason, the Scheme method of the returned Hash may return a value that\n// isn't in one of the HashScheme constants in this package.\n//\n// This function doesn't verify that the value portion of the given hash makes\n// sense for the given scheme. Invalid values are just considered to not match\n// any packages.\n//\n// If this function returns an error then the returned Hash is invalid and\n// must not be used.\nfunc ParseHash(s string) (Hash, error) {\n\tcolon := strings.Index(s, \":\")\n\tif colon < 1 { // 1 because a zero-length scheme is not allowed\n\t\treturn NilHash, fmt.Errorf(\"hash string must start with a scheme keyword followed by a colon\")\n\t}\n\treturn Hash(s), nil\n}\n\n// MustParseHash is a wrapper around ParseHash that panics if it returns an\n// error.\nfunc MustParseHash(s string) Hash {\n\thash, err := ParseHash(s)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\treturn hash\n}\n\n// Scheme returns the scheme of the recieving hash. If the receiver is not\n// using valid syntax then this method will panic.\nfunc (h Hash) Scheme() HashScheme {\n\tcolon := strings.Index(string(h), \":\")","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/getproviders/providerreqs/hash.go#L30-L66","documentation":"Thrown by ParseHash when the input string does not contain a colon at index >= 1. Hash values are scheme-prefixed (e.g. 'zh:' for zip-hash, 'h1:' for HMAC), so a zero-length scheme or a missing colon is invalid. The returned Hash is NilHash and must not be used.","triggerScenarios":"ParseHash(s) where strings.Index(s, ':') < 1 — i.e. no colon present, or the string begins with a colon (empty scheme).","commonSituations":"Lock file or checksum list containing a bare hex digest without a scheme prefix; legacy/plain SHA256 pasted in; a malformed 'hashes' entry built by string concatenation that dropped the prefix; upstream lock-file format regression.","solutions":["Prefix the digest with the correct scheme (commonly 'zh:' for zip archives, 'h1:' for dir hashing)","Regenerate the lock file with the toolchain so scheme prefixes are emitted","Strip whitespace/newlines from the hash string before parsing"],"exampleFix":"// before\nh, err := getproviders.ParseHash(strings.TrimSpace(line))\n// line = \"f3d2...\"  (no scheme) -> error\n\n// after\n// line = \"zh:f3d2...\"\nh, err := getproviders.ParseHash(strings.TrimSpace(line))","handlingStrategy":"validation","validationCode":"// Validate scheme+colon presence before calling ParseHash.\nfunc validHashFormat(s string) bool {\n    c := strings.Index(s, \":\")\n    return c >= 1 // non-empty scheme followed by a colon\n}\n\nif !validHashFormat(raw) {\n    return fmt.Errorf(\"hash %q is missing a scheme prefix (e.g. 'zh:', 'h1:')\", raw)\n}","typeGuard":"func IsSchemedHash(s string) bool {\n    c := strings.Index(s, \":\")\n    return c >= 1\n}","tryCatchPattern":"h, err := getproviders.ParseHash(raw)\nif err != nil {\n    return fmt.Errorf(\"invalid hash %q: expected '<scheme>:<digest>': %w\", raw, err)\n}","preventionTips":["Always emit hashes with their scheme prefix from code that generates lock files","Strip whitespace before parsing to avoid false negatives","Reject bare hex digests at the input boundary"],"tags":["hash","validation","lockfile","checksum","scheme"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}