hashicorp/terraform · error
hash string must start with a scheme keyword followed by a…
Error message
hash string must start with a scheme keyword followed by a colon
What it means
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.
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
Example fix
// before h, err := getproviders.ParseHash(strings.TrimSpace(line)) // line = "f3d2..." (no scheme) -> error // after // line = "zh:f3d2..." h, err := getproviders.ParseHash(strings.TrimSpace(line))
Defensive patterns
Strategy: validation
Validate before calling
// Validate scheme+colon presence before calling ParseHash.
func validHashFormat(s string) bool {
c := strings.Index(s, ":")
return c >= 1 // non-empty scheme followed by a colon
}
if !validHashFormat(raw) {
return fmt.Errorf("hash %q is missing a scheme prefix (e.g. 'zh:', 'h1:')", raw)
} Type guard
func IsSchemedHash(s string) bool {
c := strings.Index(s, ":")
return c >= 1
} Try / catch
h, err := getproviders.ParseHash(raw)
if err != nil {
return fmt.Errorf("invalid hash %q: expected '<scheme>:<digest>': %w", raw, err)
} Prevention
- 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
When it happens
Trigger: ParseHash(s) where strings.Index(s, ':') < 1 — i.e. no colon present, or the string begins with a colon (empty scheme).
Common situations: 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.
Related errors
- archive has incorrect checksum
- failed to verify provider package checksums
- provider package doesn't match the any of the expected…
- provider package doesn't match the expected checksum
- registry response includes invalid download URL: must use…
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/9fa97a7bde5fc0a8.
Report an issue: GitHub.
Appendix: source
Thrown at internal/getproviders/providerreqs/hash.go:48
// ParseHash parses the string representation of a Hash into a Hash value.
//
// A particular version of Terraform only supports a fixed set of hash schemes,
// but this function intentionally allows unrecognized schemes so that we can
// silently ignore other schemes that may be introduced in the future. For
// that reason, the Scheme method of the returned Hash may return a value that
// isn't in one of the HashScheme constants in this package.
//
// This function doesn't verify that the value portion of the given hash makes
// sense for the given scheme. Invalid values are just considered to not match
// any packages.
//
// If this function returns an error then the returned Hash is invalid and
// must not be used.
func ParseHash(s string) (Hash, error) {
colon := strings.Index(s, ":")
if colon < 1 { // 1 because a zero-length scheme is not allowed
return NilHash, fmt.Errorf("hash string must start with a scheme keyword followed by a colon")
}
return Hash(s), nil
}
// MustParseHash is a wrapper around ParseHash that panics if it returns an
// error.
func MustParseHash(s string) Hash {
hash, err := ParseHash(s)
if err != nil {
panic(err.Error())
}
return hash
}
// Scheme returns the scheme of the recieving hash. If the receiver is not
// using valid syntax then this method will panic.
func (h Hash) Scheme() HashScheme {
colon := strings.Index(string(h), ":")View on GitHub (pinned to d32a084675)