{"record":{"id":"09f5646551c5a727","repo":"ipfs/kubo","slug":"provide-dht-interval-v-must-be-less-than-or-equ","errorCode":null,"errorMessage":"Provide.DHT.Interval (%v) must be less than or equal to DHT provider record validity (%v)","messagePattern":"Provide\\.DHT\\.Interval \\((.+?)\\) must be less than or equal to DHT provider record validity \\((.+?)\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"config/provide.go","lineNumber":215,"sourceCode":"\t// Validate Provide.Strategy\n\tstrategy := cfg.Strategy.WithDefault(DefaultProvideStrategy)\n\tif _, err := ParseProvideStrategy(strategy); err != nil {\n\t\treturn fmt.Errorf(\"Provide.Strategy: %w\", err)\n\t}\n\n\t// Validate Provide.BloomFPRate\n\tif !cfg.BloomFPRate.IsDefault() {\n\t\trate := cfg.BloomFPRate.WithDefault(DefaultProvideBloomFPRate)\n\t\tif rate < MinProvideBloomFPRate {\n\t\t\treturn fmt.Errorf(\"Provide.BloomFPRate must be >= %d (1 in 1M), got %d\", MinProvideBloomFPRate, rate)\n\t\t}\n\t}\n\n\t// Validate Provide.DHT.Interval\n\tif !cfg.DHT.Interval.IsDefault() {\n\t\tinterval := cfg.DHT.Interval.WithDefault(DefaultProvideDHTInterval)\n\t\tif interval > amino.DefaultProvideValidity {\n\t\t\treturn fmt.Errorf(\"Provide.DHT.Interval (%v) must be less than or equal to DHT provider record validity (%v)\", interval, amino.DefaultProvideValidity)\n\t\t}\n\t\tif interval < 0 {\n\t\t\treturn fmt.Errorf(\"Provide.DHT.Interval must be non-negative, got %v\", interval)\n\t\t}\n\t\t// Provide.DHT.Interval=0 used to disable the entire provide system as a\n\t\t// side effect. It now disables only the periodic reprovide schedule:\n\t\t// new CIDs still announce via fast-provide-root and 'ipfs provide once'.\n\t\t// Operators upgrading from earlier kubo versions must opt in to one of\n\t\t// the two semantics by setting Provide.Enabled explicitly:\n\t\t//   - Provide.Enabled=false fully disables providing (the old behaviour).\n\t\t//   - Provide.Enabled=true keeps ad-hoc providing while disabling the\n\t\t//     periodic reprovide schedule.\n\t\tif interval == 0 && cfg.Enabled == Default {\n\t\t\treturn fmt.Errorf(\"Provide.DHT.Interval=0 no longer disables the provide system on its own; set Provide.Enabled explicitly: \" +\n\t\t\t\t\"Provide.Enabled=false to fully disable providing, or Provide.Enabled=true to keep ad-hoc 'ipfs provide once' \" +\n\t\t\t\t\"and fast-provide-root working while skipping the periodic reprovide schedule\")\n\t\t}\n\t}","sourceCodeStart":197,"sourceCodeEnd":233,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/config/provide.go#L197-L233","documentation":"DHT provider records expire after amino.DefaultProvideValidity; if the reprovide interval Provide.DHT.Interval exceeds that validity, records would lapse and content would disappear from the DHT between reprovides. ValidateProvideConfig rejects any explicitly set interval greater than the record validity to keep announcements continuous.","triggerScenarios":"Node startup with Provide.DHT.Interval explicitly set to a duration longer than amino.DefaultProvideValidity (24h in go-libp2p-kad-dht), e.g. \"48h\", via config file or `ipfs config --json Provide.DHT.Interval '\"48h\"'`.","commonSituations":"Operator trying to reduce DHT traffic stretches the reprovide interval past the record lifetime; copied interval from another implementation or docs assuming no upper bound.","solutions":["Lower Provide.DHT.Interval to a duration <= amino.DefaultProvideValidity (the default is 22h, leaving headroom under the 24h validity)","Remove Provide.DHT.Interval to restore the 22h default","If reducing DHT traffic is the goal, use Provide.Strategy (e.g. \"pinned+unique\") instead of stretching the interval"],"exampleFix":"// before\n\"Interval\": \"48h\"\n// after\n\"Interval\": \"22h\"","handlingStrategy":"validation","validationCode":"if iv := cfg.Provide.DHT.Interval.WithDefault(config.DefaultProvideDHTInterval); !cfg.Provide.DHT.Interval.IsDefault() && iv > amino.DefaultProvideValidity {\n\treturn fmt.Errorf(\"interval %v exceeds provider record validity %v\", iv, amino.DefaultProvideValidity)\n}","typeGuard":null,"tryCatchPattern":"if err := config.ValidateProvideConfig(cfg.Provide); err != nil {\n\tif strings.Contains(err.Error(), \"less than or equal to DHT provider record validity\") {\n\t\tcfg.Provide.DHT.Interval = nil // use 22h default\n\t}\n\treturn err\n}","preventionTips":["Keep the interval below amino.DefaultProvideValidity (24h); default 22h leaves headroom","Reduce DHT traffic via Provide.Strategy instead of stretching the interval","Re-validate after any go-libp2p-kad-dht upgrade that could change validity"],"tags":["config","validation","dht","reprovide"],"backgroundTag":"config-value-above-maximum","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"}