ipfs/kubo · error
Provide.DHT.SendProviderRecordTimeout must be positive, got
Error message
Provide.DHT.SendProviderRecordTimeout must be positive, got %v
What it means
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.
Source
Thrown at config/provide.go:287
batchSize := cfg.DHT.KeystoreBatchSize.WithDefault(DefaultProvideDHTKeystoreBatchSize)
if batchSize <= 0 {
return fmt.Errorf("Provide.DHT.KeystoreBatchSize must be positive, got %d", batchSize)
}
}
// Validate OfflineDelay
if !cfg.DHT.OfflineDelay.IsDefault() {
delay := cfg.DHT.OfflineDelay.WithDefault(DefaultProvideDHTOfflineDelay)
if delay < 0 {
return fmt.Errorf("Provide.DHT.OfflineDelay must be non-negative, got %v", delay)
}
}
// Validate SendProviderRecordTimeout
if !cfg.DHT.SendProviderRecordTimeout.IsDefault() {
timeout := cfg.DHT.SendProviderRecordTimeout.WithDefault(DefaultProvideDHTSendProviderRecordTimeout)
if timeout <= 0 {
return fmt.Errorf("Provide.DHT.SendProviderRecordTimeout must be positive, got %v", timeout)
}
}
return nil
}
// ShouldProvideForStrategy determines if content should be provided based on the provide strategy
// and content characteristics (pinned status, root status, MFS status).
func ShouldProvideForStrategy(strategy ProvideStrategy, isPinned bool, isPinnedRoot bool, isMFS bool) bool {
if strategy&ProvideStrategyAll != 0 {
// 'all' strategy: always provide
return true
}
// For combined strategies, check each component
if strategy&ProvideStrategyPinned != 0 && isPinned {
return true
}View on GitHub (pinned to 329838acdf)
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.
Example fix
// before (config.json)
"Provide": { "DHT": { "SendProviderRecordTimeout": "0s" } }
// after
"Provide": { "DHT": { "SendProviderRecordTimeout": "30s" } } Defensive patterns
Strategy: validation
Validate before calling
d, err := time.ParseDuration(raw)
if err != nil || d <= 0 {
return fmt.Errorf("SendProviderRecordTimeout must be a positive duration, got %q", raw)
} Try / catch
if err := config.ValidateProvideConfig(cfg); err != nil { log.Fatalf("invalid provide config: %v", err) } Prevention
- 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
When it happens
Trigger: 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.
Common situations: Trying to make provider record sends 'never time out' with 0 (the wrong direction), copy-pasting placeholder values, or scripts computing negative durations.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Provide.DHT.KeystoreBatchSize must be positive, got %d
- Provide.DHT.OfflineDelay must be non-negative, got %v
- method name %q is missing from Routing.Methods config param
- method name %q is not a supported method on Routing.Methods
- 'mounts' field is missing or not an array
AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03).
Data as JSON: /api/errors/b97ce98b4664cefc.
Report an issue: GitHub.