hashicorp/terraform · error

too many redirects

Error message

too many redirects

What it means

The mirror HTTP client installs a CheckRedirect hook that aborts once more than 5 redirects have been followed (len(via) > 5), to avoid hanging on redirect loops. When the cap is exceeded the request fails with this error, which the caller wraps in ErrQueryFailed. It indicates either a genuine loop or an over-long redirect chain on the mirror.

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 c9def3e214)

Solutions

  1. Reproduce the chain with curl -ILv <mirror-url>/<host>/<ns>/<type>/index.json and fix the server so the final URL is reached within 5 hops.
  2. Correct the configured base URL (scheme, host, path prefix, trailing slash) so no redirect is needed.
  3. Eliminate http->https->http bounces by serving HTTPS end-to-end on the mirror.

Example fix

# before
provider_installation {
  network_mirror { url = "http://mirror.local/tf/" }   # bounces http<->https
}

# after
provider_installation {
  network_mirror { url = "https://mirror.local/tf/" }
}
Defensive patterns

Strategy: try-catch

Try / catch

var qf getproviders.ErrQueryFailed
if errors.As(err, &qf) && strings.Contains(qf.Error(), "too many redirects") {
    // log final URL from qf.MirrorURL, alert the mirror operator
}

Prevention

When it happens

Trigger: A GET to the mirror's index.json or <version>.json endpoint receives a chain of more than five 301/302/303/307/308 responses. Typical causes: a reverse proxy or CDN that rewrites the path on each hop, an http<->https bounce, or a missing-trailing-slash rule that redirects to itself.

Common situations: Mirror fronted by a misconfigured load balancer/ingress; TLS redirect loop because the mirror forces HTTPS but the client request is already HTTPS yet rewritten; base URL missing a required path prefix so the server keeps redirecting.

Related errors


AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07). Data as JSON: /api/errors/0f02596f4ad8c1ca. Report an issue: GitHub.