{"record":{"id":"3d89cd6e8332565e","repo":"hashicorp/terraform","slug":"failed-to-retrieve-cryptographic-signature-for-pro","errorCode":null,"errorMessage":"failed to retrieve cryptographic signature for provider: %s","messagePattern":"failed to retrieve cryptographic signature for provider: (.+?)","errorType":"exception","errorClass":"ErrQueryFailed","httpStatus":null,"severity":"error","filePath":"internal/getproviders/registry_client.go","lineNumber":348,"sourceCode":"\tif err != nil {\n\t\treturn PackageMeta{}, c.errQueryFailed(\n\t\t\tprovider,\n\t\t\tfmt.Errorf(\"failed to retrieve authentication checksums for provider: %s\", err),\n\t\t)\n\t}\n\tsignatureURL, err := url.Parse(body.SHA256SumsSignatureURL)\n\tif err != nil {\n\t\treturn PackageMeta{}, fmt.Errorf(\"registry response includes invalid SHASUMS signature URL: %s\", err)\n\t}\n\tsignatureURL = resp.Request.URL.ResolveReference(signatureURL)\n\tif signatureURL.Scheme != \"http\" && signatureURL.Scheme != \"https\" {\n\t\treturn PackageMeta{}, fmt.Errorf(\"registry response includes invalid SHASUMS signature URL: must use http or https scheme\")\n\t}\n\tsignature, err := c.getFile(signatureURL)\n\tif err != nil {\n\t\treturn PackageMeta{}, c.errQueryFailed(\n\t\t\tprovider,\n\t\t\tfmt.Errorf(\"failed to retrieve cryptographic signature for provider: %s\", err),\n\t\t)\n\t}\n\n\tkeys := make([]SigningKey, len(body.SigningKeys.GPGPublicKeys))\n\tfor i, key := range body.SigningKeys.GPGPublicKeys {\n\t\tkeys[i] = *key\n\t}\n\n\tret.Authentication = PackageAuthenticationAll(\n\t\tNewMatchingChecksumAuthentication(document, body.Filename, checksum),\n\t\tNewArchiveChecksumAuthentication(ret.TargetPlatform, checksum),\n\t\tNewSignatureAuthentication(document, signature, keys),\n\t)\n\n\treturn ret, nil\n}\n\n// findClosestProtocolCompatibleVersion searches for the provider version with the closest protocol match.","sourceCodeStart":330,"sourceCodeEnd":366,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/getproviders/registry_client.go#L330-L366","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: signature host blocked by firewall\n$ terraform init\nError: failed to retrieve cryptographic signature for provider: 503 Service Unavailable returned from releases.hashicorp.com\n// after: allowlist the host and bump retry budget\n$ export TF_REGISTRY_DISCOVERY_RETRY=5\n$ terraform init","handlingStrategy":"retry","validationCode":"// Pre-flight reachability check (optional) before terraform init.\nfunc canReach(ctx context.Context, u string) bool {\n    req, _ := http.NewRequestWithContext(ctx, \"HEAD\", u, nil)\n    resp, err := http.DefaultClient.Do(req)\n    if err != nil { return false }\n    defer resp.Body.Close()\n    return resp.StatusCode == 200\n}","typeGuard":null,"tryCatchPattern":"// In Go callers wrapping getproviders.\nfor i := 0; i < 3; i++ {\n    _, err := source.PackageMeta(ctx, provider, version, platform)\n    if err == nil { break }\n    var qf getproviders.ErrQueryFailed\n    if errors.As(err, &qf) && isTransient(qf.Unwrap()) {\n        time.Sleep(backoff(i)); continue\n    }\n    return err\n}","preventionTips":["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."],"tags":["registry","network","signature","retry","getproviders"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}