ipfs/kubo · error

provider: +unique requires pinned and/or mfs

Error message

provider: +unique requires pinned and/or mfs

What it means

A configuration error raised during a '+unique' reprovide cycle: the Provide.Strategy includes the '+unique' modifier but neither the 'pinned' nor the 'mfs' base strategy is enabled. '+unique' is a modifier that deduplicates walking; it needs at least one base source of CIDs to walk. The cycle is aborted before any providing happens.

Source

Thrown at core/node/provider.go:1377

			case basePinned && baseMFS:
				// MFS first: walk MFS (locality-filtered), then pinned.
				// NewConcatProvider (not NewPrioritizedProvider) because
				// the shared bloom tracker already guarantees each CID
				// is emitted at most once -- no need for a second dedup
				// layer. NewBufferedProvider decouples the pinned
				// provider so the pinner lock is released promptly.
				inner = provider.NewConcatProvider(
					makeMFSProv(in.MFSRoot, in.Blockstore, tracker),
					provider.NewBufferedProvider(
						makePinProv(in.Pinner, in.Blockstore, tracker)),
				)
			case basePinned:
				inner = provider.NewBufferedProvider(
					makePinProv(in.Pinner, in.Blockstore, tracker))
			case baseMFS:
				inner = makeMFSProv(in.MFSRoot, in.Blockstore, tracker)
			default:
				return nil, fmt.Errorf("provider: +unique requires pinned and/or mfs")
			}

			// wrap inner channel to persist bloom count on successful close
			innerCh, err := inner(ctx)
			if err != nil {
				return nil, err
			}

			ch := make(chan cid.Cid)
			go func() {
				defer func() {
					if ctx.Err() == nil {
						persistUniqueCount(ds, tracker.Count())
					}
					providerLog.Infow("unique reprovide cycle finished",
						"providedCIDs", tracker.Count(),
						"skippedBranches", tracker.Deduplicated())
					close(ch)

View on GitHub (pinned to 329838acdf)

Solutions

  1. Set Provide.Strategy to include a base: e.g. 'pinned+mfs+unique' or 'pinned+unique' via 'ipfs config Provide.Strategy pinned+mfs+unique'
  2. Run 'ipfs config show' to verify the current strategy string
  3. Restart the daemon after fixing the config

Example fix

// before (config.json)
"Provide": { "Strategy": "unique" }
// after
"Provide": { "Strategy": "pinned+mfs+unique" }
Defensive patterns

Strategy: validation

Validate before calling

// validate strategy before writing config:
// go run: config.ParseProvideStrategy("pinned+mfs+unique") must not error,
// and +unique must be combined with pinned and/or mfs.
strategy := "pinned+mfs+unique" // not "unique" alone

Prevention

When it happens

Trigger: Setting Provide.Strategy to something like 'unique' or 'entities+unique' without 'pinned' and/or 'mfs' (valid combos are pinned+mfs+unique etc.), then a reprovide cycle runs createKeyProvider and hits the default switch case.

Common situations: Hand-editing Provide.Strategy in the kubo config or following outdated docs/flags that list '+unique' without a base strategy.

Related errors


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