{"record":{"id":"9ae578fe06c9b74c","repo":"ipfs/kubo","slug":"unexpected-redirect","errorCode":null,"errorMessage":"unexpected redirect","messagePattern":"unexpected redirect","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/rpc/api.go","lineNumber":179,"sourceCode":"func NewURLApiWithClient(url string, c *http.Client) (*HttpApi, error) {\n\tdecoder := legacy.NewDecoder()\n\t// Add support for these codecs to match what is done in the merkledag library\n\t// Note: to match prior behavior the go-ipld-prime CBOR decoder is manually included\n\t// TODO: allow the codec registry used to be configured by the caller not through a global variable\n\tdecoder.RegisterCodec(cid.DagProtobuf, dagpb.Type.PBNode, merkledag.ProtoNodeConverter)\n\tdecoder.RegisterCodec(cid.Raw, basicnode.Prototype.Bytes, merkledag.RawNodeConverter)\n\n\tapi := &HttpApi{\n\t\turl:         url,\n\t\thttpcli:     *c,\n\t\tHeaders:     make(map[string][]string),\n\t\tapplyGlobal: func(*requestBuilder) {},\n\t\tipldDecoder: decoder,\n\t}\n\n\t// We don't support redirects.\n\tapi.httpcli.CheckRedirect = func(_ *http.Request, _ []*http.Request) error {\n\t\treturn fmt.Errorf(\"unexpected redirect\")\n\t}\n\n\treturn api, nil\n}\n\nfunc (api *HttpApi) WithOptions(opts ...caopts.ApiOption) (iface.CoreAPI, error) {\n\toptions, err := caopts.ApiOptions(opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tsubApi := &HttpApi{\n\t\turl:     api.url,\n\t\thttpcli: api.httpcli,\n\t\tHeaders: api.Headers,\n\t\tapplyGlobal: func(req *requestBuilder) {\n\t\t\tif options.Offline {\n\t\t\t\treq.Option(\"offline\", options.Offline)","sourceCodeStart":161,"sourceCodeEnd":197,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/client/rpc/api.go#L161-L197","documentation":"The RPC HTTP client explicitly disables HTTP redirects in NewApi by setting httpcli.CheckRedirect to always return 'unexpected redirect'. The kubo RPC is a single flat /api/v0/ surface and redirects usually indicate a misconfigured endpoint (e.g. a gateway URL, a proxy login page, or trailing-slash rewrite), so the client fails fast instead of silently following to a different service.","triggerScenarios":"Pointing the RPC client at a URL that 3xx-redirects: a gateway address instead of the API port, an HTTPS/HTTP mismatch behind a proxy, a load balancer sending 301/302, or a base URL missing/extra path segments causing server-side rewrites.","commonSituations":"Users configuring http://127.0.0.1:8080 (gateway) instead of :5001 (API); reverse proxies with auto-redirect rules (http->https, /api/v0 -> /api/v0/); IPFS Desktop or cluster setups pointing at proxied endpoints; cloud deployments fronting the daemon with an ingress that redirects.","solutions":["Use the direct, non-redirecting API address (e.g. http://127.0.0.1:5001) with no trailing redirects","Test the URL with `curl -i <url>/api/v0/id` and remove whatever causes the 3xx","Reconfigure proxy/ingress to pass requests through without rewriting (disable http->https or slash redirects for /api/v0)","If a redirect is genuinely required, supply your own http.Client by constructing HttpApi with a custom option rather than relying on the default client"],"exampleFix":"// before\napi, err := rpc.NewApi(\"http://127.0.0.1:8080\") // gateway, gets redirected\n// after\napi, err := rpc.NewApi(\"http://127.0.0.1:5001\") // actual RPC API port","handlingStrategy":"validation","validationCode":"u, err := url.Parse(apiURL)\nif err != nil { return err }\nif u.Port() != \"5001\" && !strings.Contains(u.Path, \"/api/v0\") {\n    return fmt.Errorf(\"%s does not look like a kubo RPC API endpoint\", apiURL)\n}","typeGuard":null,"tryCatchPattern":"api, err := rpc.NewApi(apiURL)\nif err != nil && strings.Contains(err.Error(), \"unexpected redirect\") {\n    return fmt.Errorf(\"endpoint %s redirects; use the direct RPC address (port 5001), not a gateway or proxy: %w\", apiURL, err)\n}","preventionTips":["Point at :5001 (API), never :8080 (gateway)","Configure proxies to not rewrite/redirect /api/v0 paths","Test with `curl -i <url>/api/v0/id` — expect 200, not 3xx"],"tags":["go","ipfs","rpc","http","redirect"],"backgroundTag":"unexpected-redirect","analyzedSha":"329838acdfafae224582930457efe80aa217afc0","analyzedAt":"2026-09-03T18:30:52.135Z","contentChangedAt":"2026-09-03T18:30:52.135Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}