{"record":{"id":"7adcbe43f3cc4389","repo":"valyala/fasthttp","slug":"fasthttp-hostclient-can-t-follow-redirects-to-a-d","errorCode":null,"errorMessage":"fasthttp: hostclient can't follow redirects to a different protocol, please use client instead","messagePattern":"fasthttp: hostclient can't follow redirects to a different protocol, please use client instead","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client.go","lineNumber":1233,"sourceCode":"\tstatusCode, body, err = doRequestFollowRedirectsBuffer(req, dst, url, c)\n\n\treturn statusCode, body, err\n}\n\nvar (\n\t// ErrMissingLocation is returned by clients when the Location header is missing on\n\t// an HTTP response with a redirect status code.\n\tErrMissingLocation = errors.New(\"fasthttp: missing location header for http redirect\")\n\t// ErrTooManyRedirects is returned by clients when the number of redirects followed\n\t// exceed the max count.\n\tErrTooManyRedirects = errors.New(\"fasthttp: too many redirects detected when doing the request\")\n\t// ErrRedirectBodyStream is returned by clients when a redirect that keeps the request\n\t// body is received for a request whose body is a stream. The hop that produced the\n\t// redirect consumed the stream, so the body cannot be sent again.\n\tErrRedirectBodyStream = errors.New(\"fasthttp: cannot follow a body-preserving redirect for a request with a body stream\")\n\n\t// ErrHostClientRedirectToDifferentScheme is returned when a HostClient follows a redirect to a different protocol.\n\tErrHostClientRedirectToDifferentScheme = errors.New(\"fasthttp: hostclient can't follow redirects to a different protocol,\" +\n\t\t\" please use client instead\")\n)\n\nconst defaultMaxRedirectsCount = 16\n\n// Only drain response streams that are known to be small. Reading an unknown\n// length stream can block forever (for example, on an event stream), while\n// closing a large stream avoids transferring a body the caller discarded.\nconst maxResponseBodyDrainSize = 8 * 1024\n\nfunc closeOrDrainResponseBody(resp *Response, maxDrainSize int) error {\n\tif !resp.IsBodyStream() {\n\t\treturn nil\n\t}\n\n\tcontentLength := resp.Header.ContentLength()\n\tif contentLength < 0 || contentLength > maxDrainSize {\n\t\treturn resp.CloseBodyStream()","sourceCodeStart":1215,"sourceCodeEnd":1251,"githubUrl":"https://github.com/valyala/fasthttp/blob/c96f600972c6f4a7a30d664257b340ebe9d60124/client.go#L1215-L1251","documentation":"ErrHostClientRedirectToDifferentScheme is returned when a HostClient follows a redirect whose Location targets a different protocol (e.g. an https-bound HostClient redirected to http, or vice versa). HostClient is pinned to one scheme, so it cannot serve the redirect target; the general fasthttp.Client must be used instead.","triggerScenarios":"HostClient with IsTLS set (https) receiving a 3xx whose Location begins with http:// (or the inverse); any redirect chain crossing scheme boundaries.","commonSituations":"Services redirecting to login pages on another scheme; mixed http/https behind a load balancer; servers redirecting https traffic back to plain http.","solutions":["Switch to fasthttp.Client and use DoRedirects, which handles both schemes","Fix the server so redirects keep the same scheme (force https consistently)","Normalize the redirect Location on a proxy before it reaches the client","If you must keep HostClient, resolve the redirect target manually and use a second client for the other scheme"],"exampleFix":"// before\nhc := &fasthttp.HostClient{Addr: \"example.com:443\", IsTLS: true}\n// hc.DoRedirects -> ErrHostClientRedirectToDifferentScheme on http Location\n// after\nc := &fasthttp.Client{}\n_, _, err := c.DoRedirects(req, resp) // follows cross-scheme redirects","handlingStrategy":"validation","validationCode":"loc := string(resp.Header.Peek(fasthttp.HeaderLocation))\nif loc != \"\" && strings.HasPrefix(loc, \"http://\") == hc.IsTLS {\n    // cross-scheme redirect coming; use fasthttp.Client instead\n}","typeGuard":null,"tryCatchPattern":"if errors.Is(err, fasthttp.ErrHostClientRedirectToDifferentScheme) {\n    // re-issue the request via fasthttp.Client{} DoRedirects\n}","preventionTips":["Use fasthttp.Client when redirect targets may change scheme","Force a single scheme server-side (permanent http->https redirect)","Normalize Location headers on your proxy","Pre-resolve final URLs to keep using HostClient"],"tags":["http","redirect","tls","client"],"backgroundTag":"redirect-scheme-mismatch","analyzedSha":"c96f600972c6f4a7a30d664257b340ebe9d60124","analyzedAt":"2026-08-31T22:48:28.265Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}