{"record":{"id":"fad82f5bc86267bb","repo":"hashicorp/terraform","slug":"the-request-failed-after-d-attempts-please-try-a","errorCode":null,"errorMessage":"the request failed after %d attempts, please try again later%s","messagePattern":"the request failed after (.+?) attempts, please try again later(.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/getproviders/registry_client.go","lineNumber":490,"sourceCode":"\t// Close the body per library instructions\n\tif resp != nil {\n\t\tresp.Body.Close()\n\t}\n\n\t// Additional error detail: if we have a response, use the status code;\n\t// if we have an error, use that; otherwise nothing. We will never have\n\t// both response and error.\n\tvar errMsg string\n\tif resp != nil {\n\t\terrMsg = fmt.Sprintf(\": %s returned from %s\", resp.Status, HostFromRequest(resp.Request))\n\t} else if err != nil {\n\t\terrMsg = fmt.Sprintf(\": %s\", err)\n\t}\n\n\t// This function is always called with numTries=RetryMax+1. If we made any\n\t// retry attempts, include that in the error message.\n\tif numTries > 1 {\n\t\treturn resp, fmt.Errorf(\"the request failed after %d attempts, please try again later%s\",\n\t\t\tnumTries, errMsg)\n\t}\n\treturn resp, fmt.Errorf(\"the request failed, please try again later%s\", errMsg)\n}\n\n// HostFromRequest extracts host the same way net/http Request.Write would,\n// accounting for empty Request.Host\nfunc HostFromRequest(req *http.Request) string {\n\tif req.Host != \"\" {\n\t\treturn req.Host\n\t}\n\tif req.URL != nil {\n\t\treturn req.URL.Host\n\t}\n\n\t// this should never happen and if it does\n\t// it will be handled as part of Request.Write()\n\t// https://cs.opensource.google/go/go/+/refs/tags/go1.18.4:src/net/http/request.go;l=574","sourceCodeStart":472,"sourceCodeEnd":508,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/getproviders/registry_client.go#L472-L508","documentation":"maxRetryErrorHandler is the terminal handler for go-retryablehttp when all retry attempts are used up and numTries > 1. It reports how many attempts were made plus the last status or transport error. Default discoveryRetry is 1, so under normal config this is the common 'retries exhausted' terminal error for retryable failures (5xx, network).","triggerScenarios":"A retryable registry failure (5xx, network timeout, connection reset) persisted across all attempts. numTries equals RetryMax+1 (RetryMax from TF_REGISTRY_DISCOVERY_RETRY, default 1 -> 2 attempts).","commonSituations":"Registry or CDN transient outage; corporate proxy intermittently dropping connections; DNS flakiness; TF_REGISTRY_CLIENT_TIMEOUT too short causing repeated timeouts that exhaust retries; rate limiting (429) treated as retryable by the underlying library.","solutions":["Retry terraform init later — the failure is usually transient.","Increase TF_REGISTRY_DISCOVERY_RETRY (e.g. 3-5) to survive longer outages.","Increase TF_REGISTRY_CLIENT_TIMEOUT to avoid timeout-induced retry exhaustion.","Check connectivity to the registry host and any proxy (HTTPS_PROXY).","If a private registry, investigate its logs for the 5xx."],"exampleFix":"# before\nexport TF_REGISTRY_DISCOVERY_RETRY=1\nexport TF_REGISTRY_CLIENT_TIMEOUT=10\n# after\nexport TF_REGISTRY_DISCOVERY_RETRY=5\nexport TF_REGISTRY_CLIENT_TIMEOUT=30","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Wrap the registry call; retryable exhaustion is transient.\nfunc withRetry(ctx context.Context, fn func() error) error {\n    var err error\n    for i := 0; i < 3; i++ {\n        if err = fn(); err == nil {\n            return nil\n        }\n        if !strings.Contains(err.Error(), \"please try again later\") {\n            return err\n        }\n        select {\n        case <-time.After(time.Duration(i+1) * time.Second):\n        case <-ctx.Done():\n            return ctx.Err()\n        }\n    }\n    return err\n}","preventionTips":["Set TF_REGISTRY_DISCOVERY_RETRY (e.g. 3-5) and a comfortable TF_REGISTRY_CLIENT_TIMEOUT in CI.","Verify egress and proxy config to the registry host.","Treat 'please try again later' as transient and back off, not as a hard failure."],"tags":["terraform","registry","retry","network","transient"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T20:17:04.800Z"}