ipfs/kubo · error

ls returned more links than expected (%d)

Error message

ls returned more links than expected (%d)

What it means

Companion invariant to the objects check: after confirming exactly one object in the ls page, apiIter requires exactly one link in that object. If the object carries more (or zero) links, the iterator records this error and stops, since it exposes one directory entry (it.cur) per iteration and cannot represent multiple links in a single step.

Source

Thrown at client/rpc/apifile.go:228

		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)
		if err != nil {
			it.err = err
			return false
		}
	case unixfs.TFile:

View on GitHub (pinned to 329838acdf)

Solutions

  1. Run a kubo daemon matching the client version (version skew is the usual cause)
  2. Query the daemon directly, not through transforming proxies
  3. Verify response shape with `curl -X POST 'http://127.0.0.1:5001/api/v0/ls?arg=<cid>'`
  4. For full directory listings, call the ls RPC directly and iterate Objects/Links yourself
Defensive patterns

Strategy: retry

Validate before calling

// one object must carry exactly one link per iteration step
var out struct{ Objects []struct{ Links []struct{} `json:"Links"` } `json:"Objects"` }
_ = api.Request("ls").Option("arg", p).Exec(ctx, &out)
if len(out.Objects) == 1 && len(out.Objects[0].Links) != 1 {
    return fmt.Errorf("server batches links; use raw ls RPC")
}

Try / catch

if strings.Contains(err.Error(), "ls returned more links than expected") {
    // fall back to direct ls RPC and walk Objects[0].Links yourself
    return iterateLsDirect(ctx, api, p)
}

Prevention

When it happens

Trigger: Directory iteration via the client where a single ls response returns one object containing multiple links — typically a daemon that returns the whole directory in one object rather than one entry per response, or a changed/streaming ls response shape.

Common situations: Client talking to a non-kubo or older/newer server whose ls semantics differ; custom API re-implementations; proxies that collapse multiple responses into one object with many links.

Related errors


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