mislav/hub · error
refusing to follow HTTP %d redirect for a %s request Have yo
Error message
refusing to follow HTTP %d redirect for a %s request Have your site admin use HTTP %d for this kind of redirect
What it means
checkRedirect customizes Go's http.Client redirect policy: for HTTP 301/302 responses, the client will not follow the redirect if the HTTP method would change (per RFC, 301/302 should keep the method only informally). If the original request was not the method the recommended redirect code (303 for 301, 307 for 302) implies, it refuses and returns this error. This protects tokens/credentials in POST bodies from being silently converted to GETs or resent to a different location.
Source
Thrown at github/http.go:223
return &http.Client{
Transport: tr,
CheckRedirect: checkRedirect,
}
}
func checkRedirect(req *http.Request, via []*http.Request) error {
var recommendedCode int
switch req.Response.StatusCode {
case 301:
recommendedCode = 308
case 302:
recommendedCode = 307
}
origMethod := via[len(via)-1].Method
if recommendedCode != 0 && !strings.EqualFold(req.Method, origMethod) {
return fmt.Errorf(
"refusing to follow HTTP %d redirect for a %s request\n"+
"Have your site admin use HTTP %d for this kind of redirect",
req.Response.StatusCode, origMethod, recommendedCode)
}
// inherited from stdlib defaultCheckRedirect
if len(via) >= 10 {
return errors.New("stopped after 10 redirects")
}
return nil
}
func cloneRequest(req *http.Request) *http.Request {
dup := new(http.Request)
*dup = *req
dup.URL, _ = url.Parse(req.URL.String())
dup.Header = make(http.Header)
for k, s := range req.Header {View on GitHub (pinned to 5c547ed804)
Solutions
- Ask the site admin to return 307 (for 302) or 308 (for 301) for method-preserving redirects, as the message instructs.
- Change the configured protocol to the redirect target directly: set `protocol: https` (or the canonical host) in ~/.config/hub so no redirect occurs.
- Update the API base URL used by the client to the final destination URL.
- Fix the proxy/load-balancer rewrite rules (http->https should use 307/308 for API endpoints).
Example fix
// before (~/.config/hub) ghe.example.com: - protocol: http // after ghe.example.com: - protocol: https user: octocat oauth_token: xxxx
Defensive patterns
Strategy: validation
Validate before calling
// Pre-flight: follow the target with a HEAD request and inspect the chain:
client := &http.Client{CheckRedirect: func(req *http.Request, via []*http.Request) error { return http.ErrUseLastResponse }}
resp, _ := client.PostForm(baseURL+"/api/v3/foo", url.Values{})
if resp.StatusCode == 301 || resp.StatusCode == 302 {
log.Fatalf("server redirects with %d; configure the final URL directly: %s", resp.StatusCode, resp.Header.Get("Location"))
} Try / catch
if err := doAPIPost(); err != nil {
if strings.Contains(err.Error(), "refusing to follow HTTP") {
return fmt.Errorf("server/proxy misconfiguration: use 307/308 for method-preserving redirects or point the client at the final URL: %w", err)
}
return err
} Prevention
- Configure protocol: https (and the canonical host) in ~/.config/hub so no redirect occurs
- Have site admins use 307/308 for http->https rewrites of API endpoints
- Point proxy health/rewrite rules away from 301/302 for POST-bearing API routes
- Resolve redirects once at setup time and store the final base URL
When it happens
Trigger: A POST/PUT/PATCH request to a GitHub Enterprise server that answers 301 or 302, where following the redirect would change the method; checkRedirect is invoked by http.Client as the CheckRedirect hook.
Common situations: GitHub Enterprise behind a misconfigured proxy/load balancer issuing 302s to HTTPS or a canonical name for API POSTs; server admin rewriting http->https with a 302 instead of 307/308; wrong base URL (http instead of https) in hub config.
Related errors
AI-assisted analysis of mislav/hub@5c547ed804 (2026-09-01).
Data as JSON: /api/errors/b7973f301d03958f.
Report an issue: GitHub.