ipfs/kubo · error

Provide.DHT.OfflineDelay must be non-negative, got %v

Error message

Provide.DHT.OfflineDelay must be non-negative, got %v

What it means

ValidateProvideConfig rejects Provide.DHT.OfflineDelay when it is explicitly set but resolves to a negative duration. OfflineDelay controls how long the node waits after going offline before treating the provider keystore as stale, so negative values are meaningless. Validation runs during node setup and aborts startup.

Source

Thrown at config/provide.go:279

		conns := cfg.DHT.MaxProvideConnsPerWorker.WithDefault(DefaultProvideDHTMaxProvideConnsPerWorker)
		if conns <= 0 {
			return fmt.Errorf("Provide.DHT.MaxProvideConnsPerWorker must be positive, got %d", conns)
		}
	}

	// Validate KeystoreBatchSize
	if !cfg.DHT.KeystoreBatchSize.IsDefault() {
		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 {

View on GitHub (pinned to 329838acdf)

Solutions

  1. Set Provide.DHT.OfflineDelay to a non-negative duration (e.g. "0s" or "10m").
  2. Delete the Provide.DHT.OfflineDelay key so the default DefaultProvideDHTOfflineDelay is used.
  3. Inspect the value with `ipfs config Provide.DHT.OfflineDelay` and correct the sign.

Example fix

// before (config.json)
"Provide": { "DHT": { "OfflineDelay": "-5m" } }
// after
"Provide": { "DHT": { "OfflineDelay": "5m" } }
Defensive patterns

Strategy: validation

Validate before calling

d, err := time.ParseDuration(raw)
if err != nil || d < 0 {
    return fmt.Errorf("OfflineDelay must be a non-negative 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: Writing a negative duration string such as "-5s" or "-1h" to Provide.DHT.OfflineDelay (e.g. `ipfs config --json Provide.DHT.OfflineDelay '-5s'`) then starting the node or invoking IPFS construction, which calls ValidateProvideConfig.

Common situations: Attempting to 'disable' the delay with a negative sentinel, arithmetic generating negative durations, or hand-editing config.json with a typo before the duration value.

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/5876a2d3a2c04b87. Report an issue: GitHub.