hashicorp/terraform · error

unsupported hash format (this may require a newer version of

Error message

unsupported hash format (this may require a newer version of Terraform)

What it means

Raised in PackageMatchesHash (internal/getproviders/hash.go:130). The supplied hash uses a scheme prefix that is neither 'h1:' (HashScheme1) nor 'zh:' (HashSchemeZip). The current Terraform build does not know how to verify that scheme, so it cannot confirm or deny a match and returns this error. The message hints a newer Terraform may be required.

Source

Thrown at internal/getproviders/hash.go:130

	switch want.Scheme() {
	case HashScheme1:
		got, err := PackageHashV1(loc)
		if err != nil {
			return false, err
		}
		return got == want, nil
	case HashSchemeZip:
		archiveLoc, ok := loc.(PackageLocalArchive)
		if !ok {
			return false, fmt.Errorf(`ziphash scheme ("zh:" prefix) is not supported for unpacked provider packages`)
		}
		got, err := PackageHashLegacyZipSHA(archiveLoc)
		if err != nil {
			return false, err
		}
		return got == want, nil
	default:
		return false, fmt.Errorf("unsupported hash format (this may require a newer version of Terraform)")
	}
}

// PackageMatchesAnyHash returns true if the package at the given location
// matches at least one of the given hashes, or false otherwise.
//
// If it cannot read from the given location, PackageMatchesAnyHash returns an
// error. Unlike the singular PackageMatchesHash, PackageMatchesAnyHash
// considers unsupported hash formats as successfully non-matching, rather
// than returning an error.
//
// PackageMatchesAnyHash can be used only with the two local package location
// types PackageLocalDir and PackageLocalArchive, because it needs to access the
// contents of the indicated package in order to compute the hash. If given
// a non-local location this function will always return an error.
func PackageMatchesAnyHash(loc PackageLocation, allowed []providerreqs.Hash) (bool, error) {
	// It's likely that we'll have multiple hashes of the same scheme in
	// the "allowed" set, in which case we'll avoid repeatedly re-reading the

View on GitHub (pinned to c9def3e214)

Solutions

  1. Upgrade Terraform to a version that supports the hash scheme in use.
  2. Regenerate the lockfile (.terraform.lock.hcl) with the current Terraform so it records only supported schemes.
  3. Use PackageMatchesAnyHash, which silently skips unknown schemes and returns false instead of erroring.
  4. Filter the allowed hashes to supported schemes (h1:, zh:) before calling PackageMatchesHash.
Defensive patterns

Strategy: fallback

Validate before calling

// Keep only hash schemes this Terraform build can verify.
func filterSupportedHashes(hashes []Hash) []Hash {
	out := make([]Hash, 0, len(hashes))
	for _, h := range hashes {
		switch h.Scheme() {
		case HashScheme1, HashSchemeZip:
			out = append(out, h)
		}
	}
	return out
}

Try / catch

// PackageMatchesAnyHash treats unknown schemes as non-matches (no error).
ok, err := PackageMatchesAnyHash(loc, allowed)
if err != nil {
    return false, err
}

Prevention

When it happens

Trigger: Verifying against a hash from a lockfile or registry written by a newer Terraform that introduced an additional hash scheme (e.g. a future 'h2:'). The switch's default branch catches the unknown scheme.

Common situations: Downgrading Terraform after a newer version wrote a lockfile with a new hash scheme; a registry listing including hashes for newer schemes; a hand-edited lock entry with a typo'd prefix.

Related errors


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