hashicorp/terraform · error

provider mirror returned invalid provider hash %q: %s

Error message

provider mirror returned invalid provider hash %q: %s

What it means

If a version JSON archive entry includes a "hashes" array, each string is parsed with ParseHash. Any entry that is not a valid hash (e.g. not in the h1:... or zh:... form) fails the whole query via errQueryFailed with this message, quoting the bad hash and the parse error. The mirror published an invalid hash.

Source

Thrown at internal/getproviders/http_mirror_source.go:246

	ret := PackageMeta{
		Provider:       provider,
		Version:        version,
		TargetPlatform: target,

		Location: PackageHTTPURL(absURL.String()),
		Filename: path.Base(absURL.Path),
	}
	// A network mirror might not provide any hashes at all, in which case
	// the package has no source-defined authentication whatsoever.
	if len(archiveMeta.Hashes) > 0 {
		hashes := make([]Hash, 0, len(archiveMeta.Hashes))
		for _, hashStr := range archiveMeta.Hashes {
			hash, err := ParseHash(hashStr)
			if err != nil {
				return PackageMeta{}, s.errQueryFailed(
					provider,
					fmt.Errorf("provider mirror returned invalid provider hash %q: %s", hashStr, err),
				)
			}
			hashes = append(hashes, hash)
		}
		ret.Authentication = NewPackageHashAuthentication(target, hashes)
	}

	return ret, nil
}

// ForDisplay returns a string description of the source for user-facing output.
func (s *HTTPMirrorSource) ForDisplay(provider addrs.Provider) string {
	return "provider mirror at " + s.baseURL.String()
}

// ListVersionsResponseBody is the JSON structure of a response when a user queries the available versions
// for a provider in the network mirror, i.e. a GET to path :hostname/:namespace/:type/index.json
// See: https://developer.hashicorp.com/terraform/internals/provider-network-mirror-protocol#list-available-versions

View on GitHub (pinned to c9def3e214)

Solutions

  1. Inspect the version JSON and remove/fix the offending hash string.
  2. Regenerate hashes using the documented h1: algorithm (dirhash.Hash1 over the archive).
  3. If you do not want to publish hashes, omit the "hashes" field entirely (the protocol allows it).

Example fix

# before
{"hashes":["9f2e...c1"]}  # raw sha256 hex

# after
{"hashes":["h1:2f3b...="]}  # h1: base64 from dirhash.Hash1
# or omit hashes entirely
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate each published hash parses before writing the version file.
for _, h := range entry.Hashes {
    if _, err := getproviders.ParseHash(h); err != nil {
        return fmt.Errorf("hash %q invalid: %w", h, err)
    }
}

Try / catch

var qf getproviders.ErrQueryFailed
if errors.As(err, &qf) && strings.Contains(qf.Error(), "invalid provider hash") {
    // mirror published a bad hash; surface to operator
}

Prevention

When it happens

Trigger: An archive entry's hashes array contains a malformed string: missing scheme prefix, wrong algorithm prefix, base64 of wrong length, or plain garbage. Only valid h1:/zh: hashes are accepted.

Common situations: Mirror generator recorded SHA256 hex digests instead of h1: base64 hashes; copy-paste truncated a hash; mixed-in checksum from a different scheme.

Related errors


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