{"record":{"id":"8784105675db30f3","repo":"ipfs/kubo","slug":"block-s-not-found-locally-cannot-provide","errorCode":null,"errorMessage":"block %s not found locally, cannot provide","messagePattern":"block (.+?) not found locally, cannot provide","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/coreapi/routing.go","lineNumber":148,"sourceCode":"\terr = api.checkOnline(false)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\trp, _, err := api.core().ResolvePath(ctx, path)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tc := rp.RootCid()\n\n\thas, err := api.blockstore.Has(ctx, c)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif !has {\n\t\treturn fmt.Errorf(\"block %s not found locally, cannot provide\", c)\n\t}\n\n\tif settings.Recursive {\n\t\terr = provideKeysRec(ctx, api.provider, api.blockstore, []cid.Cid{c})\n\t} else {\n\t\terr = api.provider.StartProviding(false, c.Hash())\n\t}\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc provideKeysRec(ctx context.Context, prov node.DHTProvider, bs blockstore.Blockstore, cids []cid.Cid) error {\n\tprovided := cidutil.NewStreamingSet()\n\n\t// Error channel with buffer size 1 to avoid blocking the goroutine","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/core/coreapi/routing.go#L130-L166","documentation":"Provide announces a block's CID to the network, but only blocks actually present in the local blockstore can be provided (the provide system reads them to build announcements). The API checks blockstore.Has first and refuses with this error for foreign or unpinned CIDs. This enforces the no-silent-CID-injection rule: a node only announces content it locally holds.","triggerScenarios":"Calling Routing().Provide (or `ipfs routing provide`) with a CID not present in the local blockstore — e.g. a CID seen on the network but never fetched, a typo'd CID, or after the block was GC'd.","commonSituations":"Operators trying to act as a provider for content they only reference (not stored), scripts re-providing content after a garbage collection removed it, and library users providing CIDs from another node.","solutions":["Fetch/store the block locally first (e.g. `ipfs get`/cat the CID, or Pin it so GC won't remove it) before calling Provide.","Verify with `ipfs block stat <cid>` that the block exists locally.","If you only want the CID discoverable, download and pin the content on this node.","If you intended to announce for another node, do the Provide from the node that actually stores the data."],"exampleFix":"// before\nerr := api.Routing().Provide(ctx, foreignCid, false) // block absent\n// after\n_, err := api.Unixfs().Get(ctx, p, foreignCidPath) // store it (or pin)\nerr = api.Routing().Provide(ctx, foreignCid, false)","handlingStrategy":"validation","validationCode":"has, err := blockstore.Has(ctx, c)\nif err != nil {\n\treturn err\n}\nif !has {\n\treturn fmt.Errorf(\"cannot provide %s: block not stored locally; get/pin it first\", c)\n}\nerr = api.Routing().Provide(ctx, c, recursive)","typeGuard":null,"tryCatchPattern":"err := api.Routing().Provide(ctx, c, false)\nif err != nil && strings.Contains(err.Error(), \"not found locally\") {\n\t// fetch the block first, then retry\n\tif _, gerr := api.Block().Get(ctx, c); gerr != nil {\n\t\treturn gerr\n\t}\n\terr = api.Routing().Provide(ctx, c, false)\n}","preventionTips":["Only call Provide on CIDs your node has stored or pinned","Check `ipfs block stat <cid>` (or blockstore.Has) before providing","Remember GC can remove blocks: pin anything you intend to keep announcing"],"tags":["ipfs","routing","provider","blockstore"],"backgroundTag":"block-not-found-locally","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"}