{"record":{"id":"b97ce98b4664cefc","repo":"ipfs/kubo","slug":"provide-dht-sendproviderrecordtimeout-must-be-posi","errorCode":null,"errorMessage":"Provide.DHT.SendProviderRecordTimeout must be positive, got %v","messagePattern":"Provide\\.DHT\\.SendProviderRecordTimeout must be positive, got (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"config/provide.go","lineNumber":287,"sourceCode":"\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}\n\n\t// Validate SendProviderRecordTimeout\n\tif !cfg.DHT.SendProviderRecordTimeout.IsDefault() {\n\t\ttimeout := cfg.DHT.SendProviderRecordTimeout.WithDefault(DefaultProvideDHTSendProviderRecordTimeout)\n\t\tif timeout <= 0 {\n\t\t\treturn fmt.Errorf(\"Provide.DHT.SendProviderRecordTimeout must be positive, got %v\", timeout)\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// ShouldProvideForStrategy determines if content should be provided based on the provide strategy\n// and content characteristics (pinned status, root status, MFS status).\nfunc ShouldProvideForStrategy(strategy ProvideStrategy, isPinned bool, isPinnedRoot bool, isMFS bool) bool {\n\tif strategy&ProvideStrategyAll != 0 {\n\t\t// 'all' strategy: always provide\n\t\treturn true\n\t}\n\n\t// For combined strategies, check each component\n\tif strategy&ProvideStrategyPinned != 0 && isPinned {\n\t\treturn true\n\t}","sourceCodeStart":269,"sourceCodeEnd":305,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/config/provide.go#L269-L305","documentation":"ValidateProvideConfig rejects Provide.DHT.SendProviderRecordTimeout when explicitly set but resolving to zero or negative. This timeout bounds how long sending a provider record to the DHT may take; zero would mean instant failure and negative is invalid. Startup is aborted with this error.","triggerScenarios":"Setting Provide.DHT.SendProviderRecordTimeout to \"0s\" or a negative duration (e.g. `ipfs config --json Provide.DHT.SendProviderRecordTimeout '0s'`) then starting the node or running the IPFS construction path that calls ValidateProvideConfig.","commonSituations":"Trying to make provider record sends 'never time out' with 0 (the wrong direction), copy-pasting placeholder values, or scripts computing negative durations.","solutions":["Set Provide.DHT.SendProviderRecordTimeout to a positive duration (e.g. \"30s\").","Remove the key so the DefaultProvideDHTSendProviderRecordTimeout default applies.","Verify with `ipfs config Provide.DHT.SendProviderRecordTimeout` that the value is > 0."],"exampleFix":"// before (config.json)\n\"Provide\": { \"DHT\": { \"SendProviderRecordTimeout\": \"0s\" } }\n// after\n\"Provide\": { \"DHT\": { \"SendProviderRecordTimeout\": \"30s\" } }","handlingStrategy":"validation","validationCode":"d, err := time.ParseDuration(raw)\nif err != nil || d <= 0 {\n    return fmt.Errorf(\"SendProviderRecordTimeout must be a positive duration, got %q\", raw)\n}","typeGuard":null,"tryCatchPattern":"if err := config.ValidateProvideConfig(cfg); err != nil { log.Fatalf(\"invalid provide config: %v\", err) }","preventionTips":["Timeouts must be > 0; omit the key to use the default","Guard config-generation scripts against 0/negative durations","Smoke-test generated configs with ValidateProvideConfig before deploying"],"tags":["config","go","validation","timeout"],"backgroundTag":"invalid-config-value","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"}