{"record":{"id":"9fba18526ebdf22d","repo":"ipfs/kubo","slug":"n-err-server-provided-bad-node-error-message","errorCode":null,"errorMessage":"n.Err (server-provided bad-node error message)","messagePattern":"n\\.Err \\(server-provided bad-node error message\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"client/rpc/pin.go","lineNumber":245,"sourceCode":"\t\t\tif out.Err != \"\" {\n\t\t\t\tselect {\n\t\t\t\tcase res <- pinVerifyRes{err: errors.New(out.Err)}:\n\t\t\t\t\treturn\n\t\t\t\tcase <-ctx.Done():\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tbadNodes := make([]iface.BadPinNode, len(out.BadNodes))\n\t\t\tfor i, n := range out.BadNodes {\n\t\t\t\tc, err := cid.Decode(n.Cid)\n\t\t\t\tif err != nil {\n\t\t\t\t\tbadNodes[i] = badNode{cid: c, err: err}\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tif n.Err != \"\" {\n\t\t\t\t\terr = errors.New(n.Err)\n\t\t\t\t}\n\t\t\t\tbadNodes[i] = badNode{cid: c, err: err}\n\t\t\t}\n\n\t\t\tselect {\n\t\t\tcase res <- pinVerifyRes{ok: out.Ok, badNodes: badNodes}:\n\t\t\tcase <-ctx.Done():\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}()\n\n\treturn res, nil\n}\n\nfunc (api *PinAPI) core() *HttpApi {\n\treturn (*HttpApi)(api)\n}","sourceCodeStart":227,"sourceCodeEnd":263,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/client/rpc/pin.go#L227-L263","documentation":"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.","triggerScenarios":"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.","commonSituations":"Datastore corruption after a crash, unpinned-but-referenced blocks removed by GC, or disks with bad sectors hosting the blockstore.","solutions":["Iterate the returned BadNodes and re-fetch/re-add the listed CIDs from a healthy source or peer, then re-verify.","Run `ipfs repo verify` / datastore consistency checks if many blocks report errors.","If the blocks are truly missing, repin from a remote source: `ipfs dag get <cid>` from a gateway or peer, then re-add locally."],"exampleFix":"// before\nres, err := api.Pin().Verify(ctx, p) // only checks err, ignores BadNodes\n// after\nfor _, r := range results {\n    for _, bn := range r.BadNodes {\n        log.Printf(\"bad node %s: %v\", bn.Cid(), bn.Err())\n    }\n}","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"res, err := api.Pin().Verify(ctx, p)\nif err != nil { return err }\nfor _, r := range res {\n    for _, bn := range r.BadNodes {\n        if err := bn.Err(); err != nil {\n            if rerr := refetchBlock(ctx, api, bn.Cid()); rerr != nil {\n                return fmt.Errorf(\"bad node %s: %w\", bn.Cid(), err)\n            }\n        }\n    }\n}","preventionTips":["Always inspect BadNodes from Verify results, not just the top-level error","Run repo/datastore consistency checks after crashes","Keep pinned content's full DAG present; avoid GC of referenced blocks","Monitor disk health on nodes hosting the blockstore"],"tags":["pin","verify","bad-nodes","datastore"],"backgroundTag":"corrupt-block-data","analyzedSha":"329838acdfafae224582930457efe80aa217afc0","analyzedAt":"2026-09-03T18:30:52.135Z","contentChangedAt":"2026-09-03T18:30:52.135Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}