{"record":{"id":"ac7c8699cb188bc1","repo":"ipfs/kubo","slug":"provide-dht-maxprovideconnsperworker-must-be-posit","errorCode":null,"errorMessage":"Provide.DHT.MaxProvideConnsPerWorker must be positive, got %d","messagePattern":"Provide\\.DHT\\.MaxProvideConnsPerWorker must be positive, got (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"config/provide.go","lineNumber":263,"sourceCode":"\t\tworkers := cfg.DHT.DedicatedPeriodicWorkers.WithDefault(DefaultProvideDHTDedicatedPeriodicWorkers)\n\t\tif workers < 0 {\n\t\t\treturn fmt.Errorf(\"Provide.DHT.DedicatedPeriodicWorkers must be non-negative, got %d\", workers)\n\t\t}\n\t}\n\n\t// Validate DedicatedBurstWorkers\n\tif !cfg.DHT.DedicatedBurstWorkers.IsDefault() {\n\t\tworkers := cfg.DHT.DedicatedBurstWorkers.WithDefault(DefaultProvideDHTDedicatedBurstWorkers)\n\t\tif workers < 0 {\n\t\t\treturn fmt.Errorf(\"Provide.DHT.DedicatedBurstWorkers must be non-negative, got %d\", workers)\n\t\t}\n\t}\n\n\t// Validate MaxProvideConnsPerWorker\n\tif !cfg.DHT.MaxProvideConnsPerWorker.IsDefault() {\n\t\tconns := cfg.DHT.MaxProvideConnsPerWorker.WithDefault(DefaultProvideDHTMaxProvideConnsPerWorker)\n\t\tif conns <= 0 {\n\t\t\treturn fmt.Errorf(\"Provide.DHT.MaxProvideConnsPerWorker must be positive, got %d\", conns)\n\t\t}\n\t}\n\n\t// Validate KeystoreBatchSize\n\tif !cfg.DHT.KeystoreBatchSize.IsDefault() {\n\t\tbatchSize := cfg.DHT.KeystoreBatchSize.WithDefault(DefaultProvideDHTKeystoreBatchSize)\n\t\tif batchSize <= 0 {\n\t\t\treturn fmt.Errorf(\"Provide.DHT.KeystoreBatchSize must be positive, got %d\", batchSize)\n\t\t}\n\t}\n\n\t// Validate OfflineDelay\n\tif !cfg.DHT.OfflineDelay.IsDefault() {\n\t\tdelay := cfg.DHT.OfflineDelay.WithDefault(DefaultProvideDHTOfflineDelay)\n\t\tif delay < 0 {\n\t\t\treturn fmt.Errorf(\"Provide.DHT.OfflineDelay must be non-negative, got %v\", delay)\n\t\t}\n\t}","sourceCodeStart":245,"sourceCodeEnd":281,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/config/provide.go#L245-L281","documentation":"Provide.DHT.MaxProvideConnsPerWorker caps concurrent connections per worker when sending provider records in sweep mode; a value of zero or less would stall all provider-record sends. ValidateProvideConfig requires an explicitly set value to be strictly positive.","triggerScenarios":"Node startup when Provide.DHT.MaxProvideConnsPerWorker is explicitly set (non-default) to 0 or a negative integer in the config.","commonSituations":"Operator setting the value to 0 intending to pause provides (use Provide.Enabled=false instead); template config left with a placeholder 0; sign errors in scripts.","solutions":["Set Provide.DHT.MaxProvideConnsPerWorker to a positive integer (default 20)","Remove the key to use the default","To stop providing, set Provide.Enabled=false rather than zeroing worker/conns knobs"],"exampleFix":"// before\n\"MaxProvideConnsPerWorker\": 0\n// after\n\"MaxProvideConnsPerWorker\": 20","handlingStrategy":"validation","validationCode":"if c := cfg.Provide.DHT.MaxProvideConnsPerWorker; !c.IsDefault() && c.WithDefault(config.DefaultProvideDHTMaxProvideConnsPerWorker) <= 0 {\n\treturn errors.New(\"MaxProvideConnsPerWorker must be positive\")\n}","typeGuard":null,"tryCatchPattern":"if err := config.ValidateProvideConfig(cfg.Provide); err != nil {\n\tif strings.Contains(err.Error(), \"MaxProvideConnsPerWorker must be positive\") {\n\t\tcfg.Provide.DHT.MaxProvideConnsPerWorker = nil // default 20\n\t}\n\treturn err\n}","preventionTips":["Never zero this knob to pause provides; use Provide.Enabled=false","Clamp generated values to >= 1","Keep the default 20 unless benchmarking showed a need to change it"],"tags":["config","validation","dht","workers"],"backgroundTag":"config-value-below-minimum","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"}