ipfs/kubo · error

provider: error flushing MFS: %w

Error message

provider: error flushing MFS: %w

What it means

Returned by mfsWalkProvider (the +unique/+entities MFS provider) when mfsRoot.FlushMemFree(ctx) fails. FlushMemFree flushes MFS writes to the blockstore and frees memory; any datastore write error during that flush aborts the reprovide cycle before the DAG walk starts. The original datastore error is wrapped and preserved.

Source

Thrown at core/node/provider.go:1285

	}
	return mfsWalkProvider(mfsRoot, bs, tracker, walk)
}

// mfsEntityRootsProvider is the +entities counterpart. It walks with
// WalkEntityRoots, emitting only entity roots and skipping file chunks.
func mfsEntityRootsProvider(mfsRoot *mfs.Root, bs blockstore.Blockstore, tracker walker.VisitedTracker) provider.KeyChanFunc {
	walk := func(ctx context.Context, root cid.Cid, emit func(cid.Cid) bool, opts ...walker.Option) error {
		return walker.WalkEntityRoots(ctx, root, walker.NodeFetcherFromBlockstore(bs), emit, opts...)
	}
	return mfsWalkProvider(mfsRoot, bs, tracker, walk)
}

// mfsWalkProvider builds a KeyChanFunc that flushes MFS, then walks
// with the given walkFunc using a shared tracker and locality check.
func mfsWalkProvider(mfsRoot *mfs.Root, bs blockstore.Blockstore, tracker walker.VisitedTracker, walk walkFunc) provider.KeyChanFunc {
	return func(ctx context.Context) (<-chan cid.Cid, error) {
		if err := mfsRoot.FlushMemFree(ctx); err != nil {
			return nil, fmt.Errorf("provider: error flushing MFS: %w", err)
		}
		rootNode, err := mfsRoot.GetDirectory().GetNode()
		if err != nil {
			return nil, fmt.Errorf("provider: error loading MFS root: %w", err)
		}

		ch := make(chan cid.Cid)
		go func() {
			defer close(ch)
			locality := func(ctx context.Context, c cid.Cid) (bool, error) {
				return bs.Has(ctx, c)
			}
			_ = walk(ctx, rootNode.Cid(), func(c cid.Cid) bool {
				select {
				case ch <- c:
					return true
				case <-ctx.Done():
					return false

View on GitHub (pinned to 329838acdf)

Solutions

  1. Check the wrapped error in logs: disk-full and I/O errors are the usual cause; free space or fix the disk
  2. Restart the daemon to get a fresh MFS root; the periodic reprovide retries the next cycle
  3. Verify datastore health (e.g. 'ipfs repo stat', badger check/repair utilities)
  4. If context cancellation caused it, ensure the node stays up long enough for the flush to complete
Defensive patterns

Strategy: retry

Validate before calling

// ensure datastore is writable and has space before heavy operations
usage := diskUsage(repoPath)
if usage.free < minFreeBytes {
    return fmt.Errorf("insufficient free space for MFS flush")
}

Try / catch

if err := mfsRoot.FlushMemFree(ctx); err != nil {
    if ctx.Err() != nil {
        return nil, ctx.Err() // cancellation: retry later
    }
    return nil, fmt.Errorf("provider: error flushing MFS: %w", err)
}

Prevention

When it happens

Trigger: Reprovide cycle with strategies using mfs (+unique and/or +entities modifiers) when FlushMemFree hits a datastore write error, disk full, or context cancellation during flush.

Common situations: Disk full or quota exceeded on the node's datastore, corrupted datastore after unclean shutdown, slow/remote datastore timing out, or daemon shutdown cancelling the context mid-flush.

Related errors


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