ipfs/kubo · error

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

Error message

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

What it means

A negative Provide.DHT.Interval is meaningless: the interval schedules periodic reprovide rounds in time. ValidateProvideConfig rejects negative durations explicitly, after checking the upper bound against the DHT provider record validity.

Source

Thrown at config/provide.go:218

		return fmt.Errorf("Provide.Strategy: %w", err)
	}

	// Validate Provide.BloomFPRate
	if !cfg.BloomFPRate.IsDefault() {
		rate := cfg.BloomFPRate.WithDefault(DefaultProvideBloomFPRate)
		if rate < MinProvideBloomFPRate {
			return fmt.Errorf("Provide.BloomFPRate must be >= %d (1 in 1M), got %d", MinProvideBloomFPRate, rate)
		}
	}

	// Validate Provide.DHT.Interval
	if !cfg.DHT.Interval.IsDefault() {
		interval := cfg.DHT.Interval.WithDefault(DefaultProvideDHTInterval)
		if interval > amino.DefaultProvideValidity {
			return fmt.Errorf("Provide.DHT.Interval (%v) must be less than or equal to DHT provider record validity (%v)", interval, amino.DefaultProvideValidity)
		}
		if interval < 0 {
			return fmt.Errorf("Provide.DHT.Interval must be non-negative, got %v", interval)
		}
		// Provide.DHT.Interval=0 used to disable the entire provide system as a
		// side effect. It now disables only the periodic reprovide schedule:
		// new CIDs still announce via fast-provide-root and 'ipfs provide once'.
		// Operators upgrading from earlier kubo versions must opt in to one of
		// the two semantics by setting Provide.Enabled explicitly:
		//   - Provide.Enabled=false fully disables providing (the old behaviour).
		//   - Provide.Enabled=true keeps ad-hoc providing while disabling the
		//     periodic reprovide schedule.
		if interval == 0 && cfg.Enabled == Default {
			return fmt.Errorf("Provide.DHT.Interval=0 no longer disables the provide system on its own; set Provide.Enabled explicitly: " +
				"Provide.Enabled=false to fully disable providing, or Provide.Enabled=true to keep ad-hoc 'ipfs provide once' " +
				"and fast-provide-root working while skipping the periodic reprovide schedule")
		}
	}

	// Validate MaxWorkers
	if !cfg.DHT.MaxWorkers.IsDefault() {

View on GitHub (pinned to 329838acdf)

Solutions

  1. Set Provide.DHT.Interval to a non-negative duration (e.g. "22h" or "0s" for the special zero semantics)
  2. Remove the key to use the default 22h interval
  3. If zero was intended to disable reproviding, also set Provide.Enabled explicitly (see the Interval=0 error)

Example fix

// before
"Interval": "-1h"
// after
"Interval": "0s"
Defensive patterns

Strategy: validation

Validate before calling

if iv := cfg.Provide.DHT.Interval; !iv.IsDefault() && iv.WithDefault(config.DefaultProvideDHTInterval) < 0 {
	return errors.New("Provide.DHT.Interval must be non-negative")
}

Try / catch

if err := config.ValidateProvideConfig(cfg.Provide); err != nil {
	if strings.Contains(err.Error(), "must be non-negative") {
		cfg.Provide.DHT.Interval = nil
	}
	return err
}

Prevention

When it happens

Trigger: Node startup when Provide.DHT.Interval is explicitly set to a negative duration such as "-1h", typically via a malformed JSON duration string in the config or a buggy config-generation script.

Common situations: Sign typo when hand-editing the config; script computing an interval from a signed offset; misunderstanding of duration formatting in the JSON config.

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/17486891cedb49c0. Report an issue: GitHub.