hashicorp/terraform · error
too many redirects
Error message
too many redirects
What it means
`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.
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.
Example fix
// before: loop due to http<->https bounce
provider_installation {
network_mirror { url = "http://mirror.local/" }
}
// after
provider_installation {
network_mirror { url = "https://mirror.local/" }
} Defensive patterns
Strategy: retry
Validate before calling
// Sanity-check the mirror URL before constructing the source
u, err := url.Parse(mirrorURL)
if err != nil || u.Scheme != "https" || u.Host == "" {
return nil, fmt.Errorf("invalid mirror URL %q", mirrorURL)
}
// quick redirect probe
if _, err := http.Head(u.String()); err != nil {
return nil, fmt.Errorf("mirror URL unreachable: %w", err)
} Try / catch
// Retry transient redirect loops with backoff
var meta PackageMeta
err := retryDo(ctx, 3, backoff, func() error {
var e error
meta, e = s.PackageMeta(ctx, provider, version, target)
if e != nil && strings.Contains(e.Error(), "too many redirects") {
return e // retryable
}
return e
}) Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- invalid credentials for
- failed to determine request credentials
- failed to retrieve authentication checksums for provider
- invalid provider mirror base URL
- invalid response content from mirror server
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/0f02596f4ad8c1ca.
Report an issue: GitHub.
Appendix: source
Thrown at internal/getproviders/http_mirror_source.go:55
var _ Source = (*HTTPMirrorSource)(nil)
// NewHTTPMirrorSource constructs and returns a new network mirror source with
// the given base URL. The relative URL offsets defined by the HTTP mirror
// protocol will be resolve relative to the given URL.
//
// The given URL must use the "https" scheme, or this function will panic.
// (When the URL comes from user input, such as in the CLI config, it's the
// UI/config layer's responsibility to validate this and return a suitable
// error message for the end-user audience.)
func NewHTTPMirrorSource(baseURL *url.URL, creds svcauth.CredentialsSource) *HTTPMirrorSource {
httpClient := httpclient.New()
httpClient.Timeout = requestTimeout
httpClient.CheckRedirect = func(req *http.Request, via []*http.Request) error {
// If we get redirected more than five times we'll assume we're
// in a redirect loop and bail out, rather than hanging forever.
if len(via) > 5 {
return fmt.Errorf("too many redirects")
}
return nil
}
// Enforce TLS
return newHTTPMirrorSourceWithHTTPClientTLS(baseURL, creds, httpClient)
}
func NewMockHTTPMirrorSource(t *testing.T, baseURL *url.URL) *HTTPMirrorSource {
httpClient := httpclient.New()
httpClient.Timeout = requestTimeout
httpClient.CheckRedirect = func(req *http.Request, via []*http.Request) error {
// If we get redirected more than five times we'll assume we're
// in a redirect loop and bail out, rather than hanging forever.
if len(via) > 5 {
return fmt.Errorf("too many redirects")
}
return nil
}View on GitHub (pinned to d32a084675)