ipfs/kubo · error

ls returned more objects than expected (%d)

Error message

ls returned more objects than expected (%d)

What it means

The apiIter drives a paged 'ls' RPC where each page is expected to contain exactly one object with one link per entry. If the response contains len(out.Objects) != 1, the iterator records this error and stops, protecting the caller from silently misinterpreting a multi-object page as a single directory entry. It signals a contract violation by the server.

Source

Thrown at client/rpc/apifile.go:223

	return it.cur.Name
}

func (it *apiIter) Next() bool {
	if it.ctx.Err() != nil {
		it.err = it.ctx.Err()
		return false
	}

	var out lsOutput
	if err := it.dec.Decode(&out); err != nil {
		if err != io.EOF {
			it.err = err
		}
		return false
	}

	if len(out.Objects) != 1 {
		it.err = fmt.Errorf("ls returned more objects than expected (%d)", len(out.Objects))
		return false
	}

	if len(out.Objects[0].Links) != 1 {
		it.err = fmt.Errorf("ls returned more links than expected (%d)", len(out.Objects[0].Links))
		return false
	}

	it.cur = out.Objects[0].Links[0]
	c, err := cid.Parse(it.cur.Hash)
	if err != nil {
		it.err = err
		return false
	}

	switch it.cur.Type {
	case unixfs.THAMTShard, unixfs.TMetadata, unixfs.TDirectory:
		it.curFile, err = it.core.getDir(it.ctx, path.FromCid(c), int64(it.cur.Size), it.cur.Mode, it.cur.ModTime)

View on GitHub (pinned to 329838acdf)

Solutions

  1. Use matching kubo versions for client and daemon
  2. Bypass proxies/middleware that may batch or transform /api/v0/ls responses
  3. Verify with `curl -X POST http://127.0.0.1:5001/api/v0/ls?arg=<path>` that one object per response is returned
  4. If you need multi-entry listing, consume the standard ls RPC yourself instead of this single-entry iterator
Defensive patterns

Strategy: retry

Validate before calling

// verify server shape directly before iterating
var out struct{ Objects []struct{} `json:"Objects"` }
_ = api.Request("ls").Option("arg", p).Exec(ctx, &out)
if len(out.Objects) != 1 { return fmt.Errorf("server returns non-single-object ls pages") }

Try / catch

it, err := api.Unixfs().Get(ctx, p)
// iterate; if Next fails with the count error, retry against direct daemon
if strings.Contains(err.Error(), "ls returned more objects than expected") {
    return retryDirect(ctx, p) // bypass proxies
}

Prevention

When it happens

Trigger: Iterating a UnixfsAPI directory (Get->directory / ls iteration) when the daemon returns an ls page with zero or multiple objects — e.g. server behavior drift, proxy aggregation, or a response shaped by a non-kubo server.

Common situations: Mixed client/daemon versions where ls output batching changed; middleware (caching proxies) merging ls responses; implementing the API surface with a custom server that returns multiple objects per request.

Related errors


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