hashicorp/terraform · error

provider mirror returned invalid provider hash

Error message

provider mirror returned invalid provider hash %q: %s

What it means

When the mirror's archive entry includes a `hashes` array, each entry is parsed with `ParseHash`. A single unparseable hash string aborts the whole `PackageMeta` construction with this error naming the bad value.

Solutions

  1. Inspect the `hashes` array in the mirror JSON and remove/fix malformed entries.
  2. Regenerate mirror metadata so hashes use `h1:` or `zh:` form.
  3. Omit the `hashes` field entirely if the mirror cannot guarantee validity (the code tolerates absence).

Example fix

// before
{"hashes":["sha256=abcdef","h1:valid..."]}
// after
{"hashes":["h1:valid..."]}
Defensive patterns

Strategy: validation

Validate before calling

// Filter out unparseable hashes before passing them in
hashes := make([]Hash, 0, len(archiveMeta.Hashes))
for _, h := range archiveMeta.Hashes {
    if parsed, err := ParseHash(h); err == nil {
        hashes = append(hashes, parsed)
    } else {
        log.Printf("[WARN] skipping unparseable mirror hash %q: %s", h, err)
    }
}

Type guard

// isParsableHash narrows to strings ParseHash accepts
func isParsableHash(s string) bool {
    _, err := ParseHash(s)
    return err == nil
}

Try / catch

hash, err := ParseHash(hashStr)
if err != nil {
    log.Printf("[WARN] mirror hash %q invalid: %s; skipping", hashStr, err)
    continue
}

Prevention

When it happens

Trigger: `ParseHash(hashStr)` returns an error while iterating `archiveMeta.Hashes`; error at http_mirror_source.go:246.

Common situations: Mirror emits a typo'd hash (`h1:`, `zh:` prefix wrong, truncated hex); mixed-case or non-base64 payload; legacy non-prefixed SHA that `ParseHash` rejects.

Related errors


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

Appendix: 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 d32a084675)