{"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/c9def3e214014c1188faabfc4a5bde5095139765/internal/getproviders/providerreqs/hash.go#L30-L66","documentation":"From ParseHash in the providerreqs package. A Hash must begin with a non-empty alphanumeric scheme followed by a colon (e.g. 'h1:...', 'zh:...'). ParseHash finds the first ':' via strings.Index; if there is no colon, or the colon is at index 0 (empty scheme), it returns this error and NilHash. The function intentionally accepts UNKNOWN schemes (so it can ignore future schemes), but it rejects schemeless strings outright.","triggerScenarios":"ParseHash(s) called with a string that has no ':' or starts with ':'. Triggered when code reads a hash from a lock file, API response, or user input that is a bare hex digest (e.g. 'abcdef0123...') instead of a schemed hash like 'h1:abcdef...'.","commonSituations":"A .terraform.lock.hcl edited by hand where someone pasted a raw SHA256 without the 'h1:'/'zh:' prefix. A custom registry/mirror returning a plain hex checksum instead of a schemed hash. Code that constructs a Hash by string conversion instead of using HashScheme.New. A truncated hash value that lost its prefix.","solutions":["Prefix the value with the correct scheme: 'h1:' for content hashes (PackageHashV1) or 'zh:' for legacy zip SHA256 hashes.","Do not create Hash values by direct conversion; use HashScheme1.New(value) / HashSchemeZip.New(value) or ParseHash on a known-good string.","If the value came from a lock file, delete the hash entry and regenerate it with 'terraform init'.","Validate hash strings with ParseHash before persisting them, so malformed values are caught at write time."],"exampleFix":"// before\nh, err := providerreqs.ParseHash(\"9c7f8a2b...\") // raw hex, no scheme\n// after\nh, err := providerreqs.ParseHash(\"h1:9c7f8a2b...\")\n// or construct correctly\nh := providerreqs.HashScheme1.New(\"9c7f8a2b...\")","handlingStrategy":"validation","validationCode":"// Validate every hash string at the boundary where it enters your system.\nfunc validateHashes(hs []string) error {\n    for _, s := range hs {\n        if _, err := providerreqs.ParseHash(s); err != nil {\n            return fmt.Errorf(\"invalid hash %q: %w\", s, err)\n        }\n    }\n    return nil\n}","typeGuard":"// Type guard for already-parsed Hash values vs raw strings.\nfunc isValidHash(s string) bool {\n    _, err := providerreqs.ParseHash(s)\n    return err == nil\n}","tryCatchPattern":null,"preventionTips":["Never build Hash by string concatenation; use HashScheme.New.","Validate hash strings before writing them to lock files or API responses.","Use ParseHash (not direct conversion) at every trust boundary."],"tags":["hash","validation","parsing","lock-file","scheme"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T21:17:07.882Z"}