hashicorp/terraform · error

hash string must start with a scheme keyword followed by a c

Error message

hash string must start with a scheme keyword followed by a colon

What it means

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.

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 c9def3e214)

Solutions

  1. Prefix the value with the correct scheme: 'h1:' for content hashes (PackageHashV1) or 'zh:' for legacy zip SHA256 hashes.
  2. Do not create Hash values by direct conversion; use HashScheme1.New(value) / HashSchemeZip.New(value) or ParseHash on a known-good string.
  3. If the value came from a lock file, delete the hash entry and regenerate it with 'terraform init'.
  4. Validate hash strings with ParseHash before persisting them, so malformed values are caught at write time.

Example fix

// before
h, err := providerreqs.ParseHash("9c7f8a2b...") // raw hex, no scheme
// after
h, err := providerreqs.ParseHash("h1:9c7f8a2b...")
// or construct correctly
h := providerreqs.HashScheme1.New("9c7f8a2b...")
Defensive patterns

Strategy: validation

Validate before calling

// Validate every hash string at the boundary where it enters your system.
func validateHashes(hs []string) error {
    for _, s := range hs {
        if _, err := providerreqs.ParseHash(s); err != nil {
            return fmt.Errorf("invalid hash %q: %w", s, err)
        }
    }
    return nil
}

Type guard

// Type guard for already-parsed Hash values vs raw strings.
func isValidHash(s string) bool {
    _, err := providerreqs.ParseHash(s)
    return err == nil
}

Prevention

When it happens

Trigger: 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...'.

Common situations: 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.

Related errors


AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07). Data as JSON: /api/errors/9fa97a7bde5fc0a8. Report an issue: GitHub.