ipfs/kubo · error
+unique/+entities must combine with pinned and/or mfs in %q
Error message
+unique/+entities must combine with pinned and/or mfs in %q
What it means
The dedup modifiers '+unique' and '+entities' only make sense when a base strategy walks DAGs (pinned and/or mfs); without such a base there is nothing to deduplicate. ParseProvideStrategy enforces this dependency and returns this error when unique/entities bits are set with no pinned/mfs base. A related check rejects '+unique/+entities' combined with 'roots'.
Source
Thrown at config/provide.go:176
strategy |= ProvideStrategyMFS
case "unique":
strategy |= ProvideStrategyUnique
case "entities":
strategy |= ProvideStrategyEntities | ProvideStrategyUnique
default:
return 0, fmt.Errorf("unknown provide strategy token: %q in %q", part, s)
}
}
// "all" provides every block and cannot be combined with selective strategies
if strategy&ProvideStrategyAll != 0 && strategy != ProvideStrategyAll {
return 0, fmt.Errorf("\"all\" strategy cannot be combined with other strategies in %q", s)
}
// +unique/+entities require a base strategy that walks DAGs (pinned and/or mfs)
wantsDedup := strategy&(ProvideStrategyUnique|ProvideStrategyEntities) != 0
if wantsDedup {
walksDAGs := strategy&(ProvideStrategyPinned|ProvideStrategyMFS) != 0
if !walksDAGs {
return 0, fmt.Errorf("+unique/+entities must combine with pinned and/or mfs in %q", s)
}
if strategy&ProvideStrategyRoots != 0 {
return 0, fmt.Errorf("+unique/+entities is incompatible with roots in %q", s)
}
}
return strategy, nil
}
// MustParseProvideStrategy is like ParseProvideStrategy but panics on error.
// Use with strategy strings that have already been validated at startup.
func MustParseProvideStrategy(s string) ProvideStrategy {
strategy, err := ParseProvideStrategy(s)
if err != nil {
panic(err)
}
return strategy
}
View on GitHub (pinned to 329838acdf)
Solutions
- Add a DAG-walking base: ipfs config Provide.Strategy 'pinned+unique' or 'mfs+entities' (both pinned and mfs work)
- If 'roots' was intended as the base, note roots is incompatible with unique/entities — switch to 'pinned+unique'
- Use 'pinned+mfs+unique' if dedup should span both pinset and MFS walks
Example fix
// before ipfs config Provide.Strategy 'unique' // after ipfs config Provide.Strategy 'pinned+unique'
Defensive patterns
Strategy: validation
Validate before calling
tokens := strings.Split(s, "+")
hasDedup := slices.Contains(tokens, "unique") || slices.Contains(tokens, "entities")
hasBase := slices.Contains(tokens, "pinned") || slices.Contains(tokens, "mfs")
if hasDedup && (!hasBase || slices.Contains(tokens, "roots")) {
return fmt.Errorf("unique/entities need pinned and/or mfs, and exclude roots")
} Type guard
func validDedupCombo(s string) bool {
_, err := config.ParseProvideStrategy(s)
return err == nil
} Try / catch
strategy, err := config.ParseProvideStrategy(s)
if err != nil {
return fmt.Errorf("Provide.Strategy %q invalid: %w", s, err)
} Prevention
- Always pair '+unique'/'+entities' with 'pinned' or 'mfs'
- Never combine '+unique'/'+entities' with 'roots'
- Prefer the canonical 'pinned+mfs+unique' when in doubt
When it happens
Trigger: Setting Provide.Strategy to 'unique', 'entities', 'unique+roots', or 'entities+roots' — i.e. dedup modifiers without 'pinned' or 'mfs' — at daemon startup or via ValidateProvideConfig.
Common situations: Assuming '+unique' can stand alone or combine with 'roots' when trimming provide load; copying a partial example from documentation that omitted the required base tokens; tuning configs incrementally and dropping the base token by accident.
Related errors
- "all" strategy cannot be combined with other strategies in %
- invalid configuration: Provide.DHT.MaxWorkers cannot be 0 wh
- Routing.Type=delegated does not support content providing. S
- invalid provide strategy: empty token in %q
- unknown provide strategy token: %q in %q
AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03).
Data as JSON: /api/errors/89ad1daad8aa79a5.
Report an issue: GitHub.