hashicorp/terraform · error · ErrQueryFailed
failed to retrieve cryptographic signature for provider
Error message
failed to retrieve cryptographic signature for provider: %s
What it means
Wrapped in ErrQueryFailed and returned when c.getFile fails to download the SHASUMS signature file (the GPG detached signature over the checksums document) for a provider. The '%s' is filled with the underlying transport or non-200 error from getFile. Without the signature, the client cannot construct PackageAuthentication and refuses to return an unauthenticated PackageMeta.
Solutions
- Retry the operation; signature fetches are wrapped in retryablehttp so transient 5xx should self-heal (check TF_REGISTRY_DISCOVERY_RETRY).
- Verify the signature URL from the registry response is reachable with curl -I from the same host.
- If using a mirror, confirm the mirror serves the signature artifact at the path the metadata JSON advertises.
- Check egress firewall/proxy allowlisting for the signature hostname.
- If the underlying error is TLS, refresh the CA bundle or the certificate on the registry.
Example fix
// before: signature host blocked by firewall $ terraform init Error: failed to retrieve cryptographic signature for provider: 503 Service Unavailable returned from releases.hashicorp.com // after: allowlist the host and bump retry budget $ export TF_REGISTRY_DISCOVERY_RETRY=5 $ terraform init
Defensive patterns
Strategy: retry
Validate before calling
// Pre-flight reachability check (optional) before terraform init.
func canReach(ctx context.Context, u string) bool {
req, _ := http.NewRequestWithContext(ctx, "HEAD", u, nil)
resp, err := http.DefaultClient.Do(req)
if err != nil { return false }
defer resp.Body.Close()
return resp.StatusCode == 200
} Try / catch
// In Go callers wrapping getproviders.
for i := 0; i < 3; i++ {
_, err := source.PackageMeta(ctx, provider, version, platform)
if err == nil { break }
var qf getproviders.ErrQueryFailed
if errors.As(err, &qf) && isTransient(qf.Unwrap()) {
time.Sleep(backoff(i)); continue
}
return err
} Prevention
- Set TF_REGISTRY_DISCOVERY_RETRY and TF_REGISTRY_CLIENT_TIMEOUT generously for flaky networks.
- Mirror provider artifacts in a local filesystem source for air-gapped or unreliable environments.
- Monitor the registry status page during provisioning windows.
When it happens
Trigger: The signature URL resolved from the registry response returns HTTP non-200 (4xx/5xx), the connection times out, DNS fails, TLS handshake fails, or the response body read errors. getFile produces '%s returned from %s' on non-200, or the raw net/http error on transport failure.
Common situations: Transient registry outage or 502 from a CDN in front of registry.terraform.io; private registry where the signature endpoint is not implemented; network egress firewall blocking the signature host; expired TLS certificate on the signature bucket; signature object deleted from the storage backend while the metadata JSON still references it.
Related errors
- the request failed after
- the request failed, please try again later
- returned from
- couldn't read information for cloud run
- couldn't read plan data for cloud run
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/3d89cd6e8332565e.
Report an issue: GitHub.
Appendix: source
Thrown at internal/getproviders/registry_client.go:348
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),
)
return ret, nil
}
// findClosestProtocolCompatibleVersion searches for the provider version with the closest protocol match.View on GitHub (pinned to d32a084675)