{"record":{"id":"1ba9a53c3950521e","repo":"ipfs/kubo","slug":"unique-entities-is-incompatible-with-roots-in-q","errorCode":null,"errorMessage":"+unique/+entities is incompatible with roots in %q","messagePattern":"\\+unique/\\+entities is incompatible with roots in %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"config/provide.go","lineNumber":179,"sourceCode":"\t\tcase \"entities\":\n\t\t\tstrategy |= ProvideStrategyEntities | ProvideStrategyUnique\n\t\tdefault:\n\t\t\treturn 0, fmt.Errorf(\"unknown provide strategy token: %q in %q\", part, s)\n\t\t}\n\t}\n\t// \"all\" provides every block and cannot be combined with selective strategies\n\tif strategy&ProvideStrategyAll != 0 && strategy != ProvideStrategyAll {\n\t\treturn 0, fmt.Errorf(\"\\\"all\\\" strategy cannot be combined with other strategies in %q\", s)\n\t}\n\t// +unique/+entities require a base strategy that walks DAGs (pinned and/or mfs)\n\twantsDedup := strategy&(ProvideStrategyUnique|ProvideStrategyEntities) != 0\n\tif wantsDedup {\n\t\twalksDAGs := strategy&(ProvideStrategyPinned|ProvideStrategyMFS) != 0\n\t\tif !walksDAGs {\n\t\t\treturn 0, fmt.Errorf(\"+unique/+entities must combine with pinned and/or mfs in %q\", s)\n\t\t}\n\t\tif strategy&ProvideStrategyRoots != 0 {\n\t\t\treturn 0, fmt.Errorf(\"+unique/+entities is incompatible with roots in %q\", s)\n\t\t}\n\t}\n\treturn strategy, nil\n}\n\n// MustParseProvideStrategy is like ParseProvideStrategy but panics on error.\n// Use with strategy strings that have already been validated at startup.\nfunc MustParseProvideStrategy(s string) ProvideStrategy {\n\tstrategy, err := ParseProvideStrategy(s)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn strategy\n}\n\n// ValidateProvideConfig validates the Provide configuration according to DHT requirements.\nfunc ValidateProvideConfig(cfg *Provide) error {\n\t// Validate Provide.Strategy","sourceCodeStart":161,"sourceCodeEnd":197,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/config/provide.go#L161-L197","documentation":"ParseProvideStrategy accepts a plus-separated Provide.Strategy string and returns a bitmask. The deduplication modifiers +unique and +entities implement cross-DAG CID deduplication while walking whole DAGs, so they only make sense when the base strategy walks DAGs (pinned and/or mfs). The roots strategy announces only root CIDs without DAG traversal, which contradicts deduplication, so combining them is rejected with this error.","triggerScenarios":"Calling config.ParseProvideStrategy, MustParseProvideStrategy, ValidateProvideConfig (via IPFS node init), or OnlineProviders with a strategy string that contains both a dedup modifier (+unique or +entities) and the +roots token, e.g. \"pinned+roots+unique\" or \"roots+entities\".","commonSituations":"Operators editing Provide.Strategy in the kubo config to reduce reprovide load add +unique to an existing \"pinned+roots\" strategy; migration scripts porting older strategy strings; confusion about which tokens are mutually exclusive.","solutions":["Remove the +roots token so the strategy only uses DAG-walking bases, e.g. \"pinned+unique\" or \"pinned+mfs+entities\"","If only root CIDs are wanted, drop +unique/+entities and keep \"pinned+roots\"","Run `ipfs config Provide.Strategy \"pinned+unique\"` (or edit the config file) and restart the daemon"],"exampleFix":"// before\nipfs config Provide.Strategy 'pinned+roots+unique'\n// after\nipfs config Provide.Strategy 'pinned+unique'","handlingStrategy":"validation","validationCode":"func validStrategy(s string) bool {\n\tparts := strings.Split(s, \"+\")\n\thasDedup := slices.ContainsFunc(parts, func(p string) bool { return p == \"unique\" || p == \"entities\" })\n\tif !hasDedup { return true }\n\twalksDAGs := slices.Contains(parts, \"pinned\") || slices.Contains(parts, \"mfs\")\n\treturn walksDAGs && !slices.Contains(parts, \"roots\")\n}","typeGuard":"func isDedupStrategy(s string) bool {\n\tst, err := config.ParseProvideStrategy(s)\n\tif err != nil { return false }\n\treturn st&(config.ProvideStrategyUnique|config.ProvideStrategyEntities) != 0\n}","tryCatchPattern":"strategy, err := config.ParseProvideStrategy(userInput)\nif err != nil {\n\treturn fmt.Errorf(\"invalid Provide.Strategy %q: %w\", userInput, err)\n}","preventionTips":["Never combine +unique/+entities with +roots; pair them with pinned and/or mfs","Run `ipfs daemon` config validation (or call ParseProvideStrategy) after any strategy edit","Document intended strategy combinations in your config-management templates"],"tags":["config","validation","provide-strategy"],"backgroundTag":"incompatible-config-combination","analyzedSha":"329838acdfafae224582930457efe80aa217afc0","analyzedAt":"2026-09-03T18:30:52.135Z","contentChangedAt":"2026-09-03T18:30:52.135Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}