hashicorp/terraform · error

registry response includes invalid SHASUMS signature URL…

Error message

registry response includes invalid SHASUMS signature URL: must use http or https scheme

What it means

Raised after resolving the SHASUMS signature URL from a provider registry response when the resulting URL scheme is neither 'http' nor 'https'. The registry client refuses to fetch signature content over any other scheme (e.g. file://, ftp://, or a scheme-less URL) to prevent untrusted registries from redirecting signature retrieval to an unintended transport. It is a hard validation on body.SHA256SumsSignatureURL after it has been resolved against the request URL.

Solutions

  1. Inspect the registry response JSON for the sha256_sums_signature_url field and correct it to a fully-qualified https URL.
  2. If using a private/mirror registry, verify its response template emits an absolute https URL for signature fields.
  3. If the URL is relative on purpose, ensure the base request URL itself is http(s) so ResolveReference produces an http(s) result.
  4. Confirm no man-in-the-middle proxy is rewriting the Location/Link headers to a non-http scheme.

Example fix

// before (registry response JSON)
{"sha256_sums_signature_url": "file:///signatures/foo.sig"}
// after
{"sha256_sums_signature_url": "https://registry.example.com/v1/providers/acme/foo/1.2.0/signature"}
Defensive patterns

Strategy: validation

Validate before calling

// Validate registry-provided signature URL scheme before relying on it.
func validateSigURL(raw string, base *url.URL) error {
    u, err := url.Parse(raw)
    if err != nil { return err }
    resolved := base.ResolveReference(u)
    if resolved.Scheme != "http" && resolved.Scheme != "https" {
        return fmt.Errorf("signature URL must be http/https, got %q", resolved.Scheme)
    }
    return nil
}

Type guard

// Guard for a registry response body field.
func isHTTPURL(raw string) bool {
    u, err := url.Parse(raw)
    if err != nil { return false }
    return u.Scheme == "http" || u.Scheme == "https"
}

Prevention

When it happens

Trigger: A registry returns a SHA256SumsSignatureURL field whose value, after ResolveReference against the request URL, yields a scheme other than http/https. This happens with typos like 'htp://', with scheme-less relative values that resolve oddly, or with a malicious/misconfigured registry returning a file:// or gopher:// URL.

Common situations: Operating a private/ mirrored Terraform registry whose JSON response template has a malformed signature URL; using a filesystem-backed or in-memory test fixture that returns a relative path that resolves to a non-http scheme; corporate proxy rewriting redirects to an internal non-http scheme.

Related errors


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

Appendix: source

Thrown at internal/getproviders/registry_client.go:342

	}
	shasumsURL = resp.Request.URL.ResolveReference(shasumsURL)
	if shasumsURL.Scheme != "http" && shasumsURL.Scheme != "https" {
		return PackageMeta{}, fmt.Errorf("registry response includes invalid SHASUMS URL: must use http or https scheme")
	}
	document, err := c.getFile(shasumsURL)
	if err != nil {
		return PackageMeta{}, c.errQueryFailed(
			provider,
			fmt.Errorf("failed to retrieve authentication checksums for provider: %s", err),
		)
	}
	signatureURL, err := url.Parse(body.SHA256SumsSignatureURL)
	if err != nil {
		return PackageMeta{}, fmt.Errorf("registry response includes invalid SHASUMS signature URL: %s", err)
	}
	signatureURL = resp.Request.URL.ResolveReference(signatureURL)
	if signatureURL.Scheme != "http" && signatureURL.Scheme != "https" {
		return PackageMeta{}, fmt.Errorf("registry response includes invalid SHASUMS signature URL: must use http or https scheme")
	}
	signature, err := c.getFile(signatureURL)
	if err != nil {
		return PackageMeta{}, c.errQueryFailed(
			provider,
			fmt.Errorf("failed to retrieve cryptographic signature for provider: %s", err),
		)
	}

	keys := make([]SigningKey, len(body.SigningKeys.GPGPublicKeys))
	for i, key := range body.SigningKeys.GPGPublicKeys {
		keys[i] = *key
	}

	ret.Authentication = PackageAuthenticationAll(
		NewMatchingChecksumAuthentication(document, body.Filename, checksum),
		NewArchiveChecksumAuthentication(ret.TargetPlatform, checksum),
		NewSignatureAuthentication(document, signature, keys),

View on GitHub (pinned to d32a084675)