{"record":{"id":"63af39706002224a","repo":"ipfs/kubo","slug":"cids-didn-t-match-local-s-remote-s","errorCode":null,"errorMessage":"cids didn't match - local %s, remote %s","messagePattern":"cids didn't match - local (.+?), remote (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/rpc/dag.go","lineNumber":83,"sourceCode":"\n\t// 'format' got replaced by 'cid-codec' in https://github.com/ipfs/interface-go-ipfs-core/pull/80\n\t// but we still support it here for backward-compatibility with use of CIDv0\n\tformat := \"\"\n\tif prefix.Version == 0 {\n\t\tcidCodec = \"\"\n\t\tformat = \"v0\"\n\t}\n\n\tstat, err := api.core().Block().Put(ctx, bytes.NewReader(nd.RawData()),\n\t\toptions.Block.Hash(prefix.MhType, prefix.MhLength),\n\t\toptions.Block.CidCodec(cidCodec),\n\t\toptions.Block.Format(format),\n\t\toptions.Block.Pin(pin))\n\tif err != nil {\n\t\treturn err\n\t}\n\tif !stat.Path().RootCid().Equals(c) {\n\t\treturn fmt.Errorf(\"cids didn't match - local %s, remote %s\", c.String(), stat.Path().RootCid().String())\n\t}\n\treturn nil\n}\n\nfunc (api *httpNodeAdder) addMany(ctx context.Context, nds []format.Node, pin bool) error {\n\tfor _, nd := range nds {\n\t\t// TODO: optimize\n\t\tif err := api.add(ctx, nd, pin); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (api *HttpDagServ) AddMany(ctx context.Context, nds []format.Node) error {\n\treturn (*httpNodeAdder)(api).addMany(ctx, nds, false)\n}\n","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/client/rpc/dag.go#L65-L101","documentation":"httpNodeAdder.add builds the node locally, sends its raw bytes/links to the daemon's dag/put, and then checks that the CID the server reports back equals the CID the client computed. If they differ, the serialized bytes the daemon produced do not match what the client intended, so the client fails instead of silently returning a differently-addressed node.","triggerScenarios":"Calling api.Dag().Add with a locally built format.Node whose re-serialization on the server yields a different root CID — e.g. mismatched Codec/MhType/Version options between client and server, or a client and daemon on incompatible boxo/go-cid versions that encode the same logical node differently.","commonSituations":"Kubo daemon and go-ipfs-api/boxo client version skew (codec defaults changed), specifying opts.Dag.Codec or MhType that the daemon applies differently, or custom IPLD codecs where node encoding differs between library versions.","solutions":["Upgrade the go-ipfs-api / boxo client and the kubo daemon to matching, current versions so both encode nodes identically.","Check the Codec, MhType, and CID version options you pass to Dag().Add; make sure they match what you intend (e.g. cid.DagProtobuf vs cid.Raw).","Log both CIDs from the error message; if local is CIDv0 and remote is CIDv1 (or hashes differ), align the MhType/Version options rather than ignoring the mismatch.","If using custom IPLD codecs, verify both sides link the same go-ipld-prime / codec library versions."],"exampleFix":"// before\nnd, _ := format.NewNode(ctx, data)\napi.Dag().Add(ctx, nd, opts.Dag.MhType(0x22)) // daemon defaults differ\n// after\nnd, _ := format.NewNode(ctx, data)\napi.Dag().Add(ctx, nd, opts.Dag.MhType(mh.SHA2_256).Codec(cid.DagProtobuf)) // explicit, matches daemon","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"nd, err := format.NewNode(ctx, data)\nif err != nil { return err }\nout, err := api.Dag().Add(ctx, nd, opts)\nif err != nil {\n    var cidErr *strings.Reader // message: \"cids didn't match - local %s, remote %s\"\n    if strings.Contains(err.Error(), \"cids didn't match\") {\n        return fmt.Errorf(\"dag add: client/daemon encoding mismatch (%w); check go-ipfs-api and kubo versions and explicit MhType/Codec opts\", err)\n    }\n    return err\n}","preventionTips":["Keep go-ipfs-api/boxo and the kubo daemon on matching versions","Pass explicit MhType and Codec options instead of relying on defaults on either side","Avoid mixing custom IPLD codecs across library versions between client and daemon"],"tags":["dag","cid-mismatch","http-rpc","version-skew"],"backgroundTag":"cid-mismatch","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"}