ipfs/kubo · warning

http api returned no error and no results

Error message

http api returned no error and no results

What it means

IsPinned expects the pin/ls response to contain at least one Keys entry for the queried path; an empty list with a successful HTTP status means the daemon neither reported the pin status nor an error, so the client raises this internal-consistency error instead of returning a false answer.

Source

Thrown at client/rpc/pin.go:135

	}
	var out pinRefKeyList
	err = api.core().Request("pin/ls").
		Option("type", options.WithType).
		Option("arg", p.String()).
		Exec(ctx, &out)
	if err != nil {
		// TODO: This error-type discrimination based on sub-string matching is brittle.
		// It is addressed by this open issue: https://github.com/ipfs/go-ipfs/issues/7563
		if strings.Contains(err.Error(), "is not pinned") {
			return "", false, nil
		}
		return "", false, err
	}

	for _, obj := range out.Keys {
		return obj.Type, true, nil
	}
	return "", false, errors.New("http api returned no error and no results")
}

func (api *PinAPI) Rm(ctx context.Context, p path.Path, opts ...caopts.PinRmOption) error {
	options, err := caopts.PinRmOptions(opts...)
	if err != nil {
		return err
	}

	return api.core().Request("pin/rm", p.String()).
		Option("recursive", options.Recursive).
		Exec(ctx, nil)
}

func (api *PinAPI) Update(ctx context.Context, from path.Path, to path.Path, opts ...caopts.PinUpdateOption) error {
	options, err := caopts.PinUpdateOptions(opts...)
	if err != nil {
		return err
	}

View on GitHub (pinned to 329838acdf)

Solutions

  1. Upgrade go-ipfs-api and kubo to matching versions so the pin/ls response shape matches.
  2. Verify the endpoint is a real kubo RPC API: curl http://<api>/api/v0/pin/ls?type=direct&arg=<cid> and inspect the raw JSON.
  3. Check for proxies/middleware between the client and daemon that could alter the response body.

Example fix

// diagnose
// curl -X POST "$API/api/v0/pin/ls?arg=$CID"
// {"Keys":{"bafy...":{"Type":"recursive"}}}  <- expected; empty Keys means version/shape mismatch
Defensive patterns

Strategy: fallback

Try / catch

_, pinned, err := api.Pin().IsPinned(ctx, p)
if err != nil {
    if strings.Contains(err.Error(), "no error and no results") {
        // version/shape mismatch: fall back to listing pins
        pins, lerr := api.Pin().List(ctx)
        if lerr == nil {
            pinned = slices.ContainsFunc(pins, func(pp path.Path) bool { return pp.String() == p.String() })
        }
    } else { return err }
}

Prevention

When it happens

Trigger: api.Pin().IsPinned(ctx, p) against a daemon whose pin/ls response for the path comes back empty — typically a daemon/client version mismatch where the response field moved or was renamed, or a proxy returning 200 with an empty body.

Common situations: Old go-ipfs-api client against a newer kubo daemon (or vice versa), an HTTP proxy/API gateway stripping or reshaping the JSON response, or pointing the client at a non-kubo endpoint that answers 200 with unrelated JSON.

Related errors


AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03). Data as JSON: /api/errors/08394dfd2faf9d2a. Report an issue: GitHub.