ipfs/kubo · warning

n.Err (server-provided bad-node error message)

Error message

n.Err (server-provided bad-node error message)

What it means

While collecting bad nodes during pin verify, if a fetched node record itself carries an error string (n.Err, set when the daemon could not load/decode that block), the client converts it to a Go error and records it in badNodes[i].err. It is a per-node failure report, not a whole-request failure.

Source

Thrown at client/rpc/pin.go:245

			if out.Err != "" {
				select {
				case res <- pinVerifyRes{err: errors.New(out.Err)}:
					return
				case <-ctx.Done():
					return
				}
			}

			badNodes := make([]iface.BadPinNode, len(out.BadNodes))
			for i, n := range out.BadNodes {
				c, err := cid.Decode(n.Cid)
				if err != nil {
					badNodes[i] = badNode{cid: c, err: err}
					continue
				}

				if n.Err != "" {
					err = errors.New(n.Err)
				}
				badNodes[i] = badNode{cid: c, err: err}
			}

			select {
			case res <- pinVerifyRes{ok: out.Ok, badNodes: badNodes}:
			case <-ctx.Done():
				return
			}
		}
	}()

	return res, nil
}

func (api *PinAPI) core() *HttpApi {
	return (*HttpApi)(api)
}

View on GitHub (pinned to 329838acdf)

Solutions

  1. Iterate the returned BadNodes and re-fetch/re-add the listed CIDs from a healthy source or peer, then re-verify.
  2. Run `ipfs repo verify` / datastore consistency checks if many blocks report errors.
  3. If the blocks are truly missing, repin from a remote source: `ipfs dag get <cid>` from a gateway or peer, then re-add locally.

Example fix

// before
res, err := api.Pin().Verify(ctx, p) // only checks err, ignores BadNodes
// after
for _, r := range results {
    for _, bn := range r.BadNodes {
        log.Printf("bad node %s: %v", bn.Cid(), bn.Err())
    }
}
Defensive patterns

Strategy: fallback

Try / catch

res, err := api.Pin().Verify(ctx, p)
if err != nil { return err }
for _, r := range res {
    for _, bn := range r.BadNodes {
        if err := bn.Err(); err != nil {
            if rerr := refetchBlock(ctx, api, bn.Cid()); rerr != nil {
                return fmt.Errorf("bad node %s: %w", bn.Cid(), err)
            }
        }
    }
}

Prevention

When it happens

Trigger: api.Pin().Verify(ctx, path) where one or more blocks in the DAG fail to load on the daemon — corrupted datastore entries, blocks evicted by GC while pinned records remain, or truncated/unreadable block data.

Common situations: Datastore corruption after a crash, unpinned-but-referenced blocks removed by GC, or disks with bad sectors hosting the blockstore.

Related errors


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