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

  1. Set Provide.DHT.SendProviderRecordTimeout to a positive duration (e.g. "30s").
  2. Remove the key so the DefaultProvideDHTSendProviderRecordTimeout default applies.
  3. 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

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.

Related errors


AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03). Data as JSON: /api/errors/b97ce98b4664cefc. Report an issue: GitHub.