golang/go · error

stopped after 10 redirects

Error message

stopped after 10 redirects

What it means

checkRedirect is the http.Client.CheckRedirect used for go-get discovery fetches. It mimics net/http's limit of 10 redirects and returns this error once the hop count reaches 10, preventing redirect loops.

Source

Thrown at src/cmd/go/internal/web/http.go:71

// but rejects redirects to plain-HTTP URLs if the original URL was secure.
func securityPreservingHTTPClient(original *http.Client) *http.Client {
	c := new(http.Client)
	*c = *original
	c.CheckRedirect = func(req *http.Request, via []*http.Request) error {
		if len(via) > 0 && via[0].URL.Scheme == "https" && req.URL.Scheme != "https" {
			lastHop := via[len(via)-1].URL
			return fmt.Errorf("redirected from secure URL %s to insecure URL %s", lastHop, req.URL)
		}
		return checkRedirect(req, via)
	}
	return c
}

func checkRedirect(req *http.Request, via []*http.Request) error {
	// Go's http.DefaultClient allows 10 redirects before returning an error.
	// Mimic that behavior here.
	if len(via) >= 10 {
		return errors.New("stopped after 10 redirects")
	}
	hasGoGet1 := via[len(via)-1].URL.Query().Get("go-get") == "1"
	if hasGoGet1 {
		if len(req.URL.RawQuery) > 0 {
			req.URL.RawQuery += "&"
		}
		req.URL.RawQuery += "go-get=1"
	}

	intercept.Request(req)
	return nil
}

func get(security SecurityMode, url *urlpkg.URL) (*Response, error) {
	start := time.Now()

	if url.Scheme == "file" {
		return getFile(url)

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Fix the vanity server's redirect chain to stay under 10 hops.
  2. Bypass vanity discovery: use the direct VCS URL (e.g. go get github.com/user/repo).
  3. Audit the server for accidental redirect loops.

Example fix

# before
$ go get example.com/lib   # vanity server loops >10 redirects

# after
$ go get github.com/user/lib   # direct VCS path
Defensive patterns

Strategy: validation

Validate before calling

// Cap redirect handling when fetching vanity URLs yourself.
func limitedRedirectClient() *http.Client {
    c := *http.DefaultClient
    c.CheckRedirect = func(req *http.Request, via []*http.Request) error {
        if len(via) >= 10 { return errors.New("too many redirects") }
        return nil
    }
    return &c
}

Type guard

null

Try / catch

null

Prevention

When it happens

Trigger: Fetching a vanity-import page (or module URL) whose redirect chain exceeds 10 hops.

Common situations: Misconfigured vanity servers with redirect loops; aggressive CDN/load-balancer redirects; HTTP->HTTPS cascades.

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/e4bf78e5237e2903. Report an issue: GitHub.