ipfs/kubo · error

new root is not a valid dag-pb node: %w

Error message

new root is not a valid dag-pb node: %w

What it means

In the MFS-root replacement flow, the new root block was fetched from the blockstore but dag.DecodeProtobuf failed to parse its raw bytes as a dag-pb node, meaning the supplied CID points at a block that is not a valid dag-pb document (e.g. a raw leaf or a UnixFS node handled one step later). The root swap is aborted before any state changes.

Source

Thrown at core/commands/files.go:1788

			return fmt.Errorf("checking if new root exists: %w", err)
		}
		if !hasBlock {
			// Special case: empty dir is always available (hardcoded in boxo)
			emptyDirCid := ft.EmptyDirNode().Cid()
			if !newRootCid.Equals(emptyDirCid) {
				return fmt.Errorf("new root %s does not exist locally; fetch it first with 'ipfs block get'", enc.Encode(newRootCid))
			}
		}

		// Validate it's a directory (not a file)
		if hasBlock {
			blk, err := bs.Get(req.Context, newRootCid)
			if err != nil {
				return fmt.Errorf("reading new root block: %w", err)
			}
			pbNode, err := dag.DecodeProtobuf(blk.RawData())
			if err != nil {
				return fmt.Errorf("new root is not a valid dag-pb node: %w", err)
			}
			fsNode, err := ft.FSNodeFromBytes(pbNode.Data())
			if err != nil {
				return fmt.Errorf("new root is not a valid UnixFS node: %w", err)
			}
			if fsNode.Type() != ft.TDirectory && fsNode.Type() != ft.THAMTShard {
				return fmt.Errorf("new root must be a directory, got %s", fsNode.Type())
			}
		}

		// Get old root for display (if exists)
		var oldRootStr string
		oldRootBytes, err := localDS.Get(req.Context, node.FilesRootDatastoreKey)
		if err == nil {
			oldRootCid, err := cid.Cast(oldRootBytes)
			if err == nil {
				oldRootStr = enc.Encode(oldRootCid)
			}

View on GitHub (pinned to 329838acdf)

Solutions

  1. Verify the CID with `ipfs dag get <cid>` / `ipfs block stat` to confirm it is a dag-pb directory node.
  2. Wrap the content properly (e.g. `ipfs add --cid-codec dag-pb` on a directory) to produce a valid directory root before retrying.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at core/commands/files.go:1788 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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