{"record":{"id":"0f02596f4ad8c1ca","repo":"hashicorp/terraform","slug":"too-many-redirects","errorCode":null,"errorMessage":"too many redirects","messagePattern":"too many redirects","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/getproviders/http_mirror_source.go","lineNumber":55,"sourceCode":"\nvar _ Source = (*HTTPMirrorSource)(nil)\n\n// NewHTTPMirrorSource constructs and returns a new network mirror source with\n// the given base URL. The relative URL offsets defined by the HTTP mirror\n// protocol will be resolve relative to the given URL.\n//\n// The given URL must use the \"https\" scheme, or this function will panic.\n// (When the URL comes from user input, such as in the CLI config, it's the\n// UI/config layer's responsibility to validate this and return a suitable\n// error message for the end-user audience.)\nfunc NewHTTPMirrorSource(baseURL *url.URL, creds svcauth.CredentialsSource) *HTTPMirrorSource {\n\thttpClient := httpclient.New()\n\thttpClient.Timeout = requestTimeout\n\thttpClient.CheckRedirect = func(req *http.Request, via []*http.Request) error {\n\t\t// If we get redirected more than five times we'll assume we're\n\t\t// in a redirect loop and bail out, rather than hanging forever.\n\t\tif len(via) > 5 {\n\t\t\treturn fmt.Errorf(\"too many redirects\")\n\t\t}\n\t\treturn nil\n\t}\n\t// Enforce TLS\n\treturn newHTTPMirrorSourceWithHTTPClientTLS(baseURL, creds, httpClient)\n}\n\nfunc NewMockHTTPMirrorSource(t *testing.T, baseURL *url.URL) *HTTPMirrorSource {\n\thttpClient := httpclient.New()\n\thttpClient.Timeout = requestTimeout\n\thttpClient.CheckRedirect = func(req *http.Request, via []*http.Request) error {\n\t\t// If we get redirected more than five times we'll assume we're\n\t\t// in a redirect loop and bail out, rather than hanging forever.\n\t\tif len(via) > 5 {\n\t\t\treturn fmt.Errorf(\"too many redirects\")\n\t\t}\n\t\treturn nil\n\t}","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/getproviders/http_mirror_source.go#L37-L73","documentation":"`NewHTTPMirrorSource` configures the HTTP client with a `CheckRedirect` hook that aborts after more than five redirects to avoid infinite loops. When the standard library's redirect following calls back with `len(via) > 5`, the hook returns this error and the request is terminated.","triggerScenarios":"Any HTTP request to the network mirror follows more than five 3xx redirects; the `CheckRedirect` callback at http_mirror_source.go:53 returns an error.","commonSituations":"Mirror misconfiguration causing a redirect loop between HTTP/HTTPS or trailing-slash variants; CDN or reverse-proxy rewrite loop; auth gateway bouncing the request; stale `provider_installation` mirror block pointing at an endpoint that now redirects elsewhere.","solutions":["Verify the mirror URL in `provider_installation { network_mirror { url = ... } }` resolves cleanly with `curl -IL`.","Remove trailing-slash/protocol mismatches that cause A->B->A redirection.","Disable or fix the redirecting reverse proxy in front of the mirror.","Update the mirror URL to the final, canonical endpoint."],"exampleFix":"// before: loop due to http<->https bounce\nprovider_installation {\n  network_mirror { url = \"http://mirror.local/\" }\n}\n// after\nprovider_installation {\n  network_mirror { url = \"https://mirror.local/\" }\n}","handlingStrategy":"retry","validationCode":"// Sanity-check the mirror URL before constructing the source\nu, err := url.Parse(mirrorURL)\nif err != nil || u.Scheme != \"https\" || u.Host == \"\" {\n    return nil, fmt.Errorf(\"invalid mirror URL %q\", mirrorURL)\n}\n// quick redirect probe\nif _, err := http.Head(u.String()); err != nil {\n    return nil, fmt.Errorf(\"mirror URL unreachable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"// Retry transient redirect loops with backoff\nvar meta PackageMeta\nerr := retryDo(ctx, 3, backoff, func() error {\n    var e error\n    meta, e = s.PackageMeta(ctx, provider, version, target)\n    if e != nil && strings.Contains(e.Error(), \"too many redirects\") {\n        return e // retryable\n    }\n    return e\n})","preventionTips":["Validate the `network_mirror.url` value with `curl -IL` before relying on it.","Keep mirror URLs canonical (consistent trailing slash, scheme, host).","Avoid mirror endpoints behind auth gateways that bounce requests.","Monitor the mirror for redirect loops."],"tags":["network","mirror","redirect","http"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}