ipfs/kubo · error
unexpected redirect
Error message
unexpected redirect
What it means
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.
Source
Thrown at client/rpc/api.go:179
func NewURLApiWithClient(url string, c *http.Client) (*HttpApi, error) {
decoder := legacy.NewDecoder()
// Add support for these codecs to match what is done in the merkledag library
// Note: to match prior behavior the go-ipld-prime CBOR decoder is manually included
// TODO: allow the codec registry used to be configured by the caller not through a global variable
decoder.RegisterCodec(cid.DagProtobuf, dagpb.Type.PBNode, merkledag.ProtoNodeConverter)
decoder.RegisterCodec(cid.Raw, basicnode.Prototype.Bytes, merkledag.RawNodeConverter)
api := &HttpApi{
url: url,
httpcli: *c,
Headers: make(map[string][]string),
applyGlobal: func(*requestBuilder) {},
ipldDecoder: decoder,
}
// We don't support redirects.
api.httpcli.CheckRedirect = func(_ *http.Request, _ []*http.Request) error {
return fmt.Errorf("unexpected redirect")
}
return api, nil
}
func (api *HttpApi) WithOptions(opts ...caopts.ApiOption) (iface.CoreAPI, error) {
options, err := caopts.ApiOptions(opts...)
if err != nil {
return nil, err
}
subApi := &HttpApi{
url: api.url,
httpcli: api.httpcli,
Headers: api.Headers,
applyGlobal: func(req *requestBuilder) {
if options.Offline {
req.Option("offline", options.Offline)View on GitHub (pinned to 329838acdf)
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
Example fix
// before
api, err := rpc.NewApi("http://127.0.0.1:8080") // gateway, gets redirected
// after
api, err := rpc.NewApi("http://127.0.0.1:5001") // actual RPC API port Defensive patterns
Strategy: validation
Validate before calling
u, err := url.Parse(apiURL)
if err != nil { return err }
if u.Port() != "5001" && !strings.Contains(u.Path, "/api/v0") {
return fmt.Errorf("%s does not look like a kubo RPC API endpoint", apiURL)
} Try / catch
api, err := rpc.NewApi(apiURL)
if err != nil && strings.Contains(err.Error(), "unexpected redirect") {
return fmt.Errorf("endpoint %s redirects; use the direct RPC address (port 5001), not a gateway or proxy: %w", apiURL, err)
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- ipfs api address could not be found
- unsupported file type '%s'
- cannot parse mode %s: %s
- ls returned more objects than expected (%d)
- ls returned more links than expected (%d)
AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03).
Data as JSON: /api/errors/9ae578fe06c9b74c.
Report an issue: GitHub.