ipfs/kubo · critical

error loading filesroot from dagservice: %s

Error message

error loading filesroot from dagservice: %s

What it means

When a stored filesroot CID exists, Kubo loads the MFS root using an offline (local-only, no-network) DAGService built around the blockstore. If `offlineDag.Get(ctx, c)` fails — typically ipld.ErrNotFound when the root block is missing locally — the error is wrapped as "error loading filesroot from dagservice". Deliberately offline: a network fetch would be unsafe/slow during startup.

Source

Thrown at core/node/core.go:243

		val, err := repo.Datastore().Get(ctx, FilesRootDatastoreKey)

		switch {
		case errors.Is(err, datastore.ErrNotFound):
			nd = unixfs.EmptyDirNode()
			err := dag.Add(ctx, nd)
			if err != nil {
				return nil, fmt.Errorf("failure writing filesroot to dagstore: %s", err)
			}
		case err == nil:
			c, err := cid.Cast(val)
			if err != nil {
				return nil, err
			}

			offlineDag := merkledag.NewDAGService(blockservice.New(bs, offline.Exchange(bs)))
			rnd, err := offlineDag.Get(ctx, c)
			if err != nil {
				return nil, fmt.Errorf("error loading filesroot from dagservice: %s", err)
			}

			pbnd, ok := rnd.(*merkledag.ProtoNode)
			if !ok {
				return nil, merkledag.ErrNotProtobuf
			}

			nd = pbnd
		default:
			return nil, err
		}

		// MFS (Mutable File System) provider integration: Only pass the provider
		// to MFS when the strategy includes "mfs". MFS will call StartProviding()
		// on every DAGService.Add() operation, which is sufficient for the "mfs"
		// strategy - it ensures all MFS content gets announced as it's added or
		// modified. For non-mfs strategies, we set provider to nil to avoid
		// unnecessary providing.

View on GitHub (pinned to 329838acdf)

Solutions

  1. Recover the missing blocks: if you know the MFS root CID, fetch it from the network (`ipfs get <cid>`) on another instance or from a pinning backup, then re-add and `ipfs files cp /ipfs/<cid> /`.
  2. If the MFS tree is unrecoverable, reset it: remove the FilesRoot key so a fresh empty root is created (back up the repo first).
  3. Upgrade Kubo — recent versions fix the GC-vs-MFS wedge (ipfs/kubo#10842) so live MFS blocks are never collected.
  4. Before GC, keep MFS root pinned or run GC with care; check what was collected with `ipfs repo gc --stream-errors`.
Defensive patterns

Strategy: fallback

Validate before calling

# Check that the MFS root block exists locally before stopping the daemon
ROOT=$(ipfs files stat / --hash)
ipfs cat "$ROOT" > /dev/null && echo "root present" || echo "WARNING: root block missing; do not run repo gc"

Try / catch

// Detect the missing-block case explicitly
rnd, err := offlineDag.Get(ctx, c)
if err != nil {
    if errors.Is(err, ipld.ErrNotFound) {
        // MFS root block was GC'd or lost: restore from backup or reset MFS
        return fmt.Errorf("MFS root %s missing from local blockstore: %w", c, err)
    }
    return fmt.Errorf("error loading filesroot from dagservice: %w", err)
}

Prevention

When it happens

Trigger: Daemon startup with a filesroot CID recorded in the datastore whose root block was removed by `ipfs repo gc` (or never fetched, or the repo was copied/truncated), so the offline blockstore lookup returns not-found; also any blockstore read error, and CID type mismatch paths nearby.

Common situations: Running `ipfs repo gc` that collected unpinned MFS blocks due to the known GC-vs-MFS wedge on older versions; manually deleting blocks from the blockstore; restoring $IPFS_PATH/datastore from a partial backup; copying a repo between machines without all blocks.

Related errors


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