{"record":{"id":"227749eefec48be9","repo":"chenhg5/cc-connect","slug":"too-many-redirects-227749","errorCode":null,"errorMessage":"too many redirects","messagePattern":"too many redirects","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/updater.go","lineNumber":177,"sourceCode":"\tvar err error\n\tif goos == \"windows\" {\n\t\tbinary, err = extractBinaryFromZip(data)\n\t} else {\n\t\tbinary, err = extractBinaryFromTarGz(data)\n\t}\n\tif err != nil {\n\t\treturn fmt.Errorf(\"extract binary: %w\", err)\n\t}\n\n\treturn replaceBinary(binary)\n}\n\nfunc downloadFile(url string) ([]byte, error) {\n\tclient := &http.Client{\n\t\tTimeout: 5 * time.Minute,\n\t\tCheckRedirect: func(req *http.Request, via []*http.Request) error {\n\t\t\tif len(via) > 10 {\n\t\t\t\treturn fmt.Errorf(\"too many redirects\")\n\t\t\t}\n\t\t\treturn nil\n\t\t},\n\t}\n\treq, err := http.NewRequest(\"GET\", url, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treq.Header.Set(\"User-Agent\", \"cc-connect-updater\")\n\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn nil, fmt.Errorf(\"HTTP %d for %s\", resp.StatusCode, url)","sourceCodeStart":159,"sourceCodeEnd":195,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/core/updater.go#L159-L195","documentation":"downloadFile (core/updater.go:177) installs an http.Client CheckRedirect hook that fails the request once the redirect chain exceeds 10 hops, returning the literal error `too many redirects`. This guards against infinite or pathological redirect loops when fetching release archives (e.g. GitHub assets redirect through objects.githubusercontent.com). The error surfaces via client.Do and is typically wrapped by error 917.","triggerScenarios":"The download URL redirects more than 10 times: a redirect loop on the release-asset host, a misconfigured CDN/proxy bouncing between URLs, cookie/auth redirects that never settle, or a rewrite loop on a mirror host. Occurs inside downloadFile during SelfUpdate.","commonSituations":"Corporate proxies rewriting release-asset URLs back to themselves; Gitee/GitHub CDN misconfiguration; caching middleware in front of the download URL looping HTTP<->HTTPS; testing against a local or staged mirror with a bad redirect config.","solutions":["Follow the URL manually with `curl -IL --max-redirs 20 <download-url>` to see the redirect chain and find the looping host.","If a corporate proxy causes the loop, bypass it for github.com/objects.githubusercontent.com/gitee.com and retry.","Retry the upgrade later if the loop is on the CDN side — it's usually a transient upstream misconfiguration.","If legitimate chains grow beyond 10, raise the `len(via) > 10` threshold to a higher cap (e.g. 20).","Point the updater at a working mirror (preferGitee toggle) so the looping source is skipped."],"exampleFix":"// before\nif len(via) > 10 {\n\treturn fmt.Errorf(\"too many redirects\")\n}\n\n// after: include the chain for diagnosis\nif len(via) > 10 {\n\tlocs := make([]string, 0, len(via))\n\tfor _, r := range via {\n\t\tlocs = append(locs, r.URL.String())\n\t}\n\treturn fmt.Errorf(\"too many redirects (>10): %s\", strings.Join(locs, \" -> \"))\n}","handlingStrategy":"retry","validationCode":"func redirectChainOK(u string) error {\n\tc := &http.Client{\n\t\tTimeout: 30 * time.Second,\n\t\tCheckRedirect: func(req *http.Request, via []*http.Request) error {\n\t\t\tif len(via) > 10 {\n\t\t\t\treturn fmt.Errorf(\"redirect chain exceeds 10: %d hops via %s\", len(via), via[len(via)-1].URL)\n\t\t\t}\n\t\t\treturn nil\n\t\t},\n\t}\n\tresp, err := c.Head(u)\n\tif err != nil {\n\t\treturn err\n\t}\n\tresp.Body.Close()\n\treturn nil\n}","typeGuard":null,"tryCatchPattern":"if err := core.SelfUpdate(tag, preferGitee); err != nil {\n\tif strings.Contains(err.Error(), \"too many redirects\") {\n\t\tslog.Warn(\"release download stuck in redirect loop; trying mirror\", \"err\", err)\n\t\t_ = core.SelfUpdate(tag, !preferGitee) // switch mirror\n\t\treturn err\n\t}\n\treturn err\n}","preventionTips":["Test the asset URL with `curl -IL --max-redirs 20` to spot redirect loops before upgrading.","Bypass misbehaving corporate proxies that rewrite asset URLs back to themselves.","Switch mirrors (preferGitee) when one download host loops.","Raise the via>10 cap only if a legitimate chain requires more hops; 10 is normally ample.","Report persistent CDN redirect loops to the release host — they are usually upstream misconfigurations."],"tags":["http","redirect","download","updater","network"],"backgroundTag":"too-many-redirects","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}