ipfs/kubo · error

Provide.DHT.Interval=0 no longer disables the provide system

Error message

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

What it means

Historically Provide.DHT.Interval=0 silently disabled the entire provide system as a side effect. Kubo now splits the semantics: Provide.Enabled=false fully disables providing, while Provide.Enabled=true keeps ad-hoc 'ipfs provide once' and fast-provide-root but skips the periodic reprovide schedule. Because Interval=0 alone is ambiguous, node startup refuses it when Provide.Enabled is left at its unset default, forcing the operator to opt in explicitly.

Source

Thrown at config/provide.go:229

	// 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() {
		maxWorkers := cfg.DHT.MaxWorkers.WithDefault(DefaultProvideDHTMaxWorkers)
		if maxWorkers <= 0 {
			return fmt.Errorf("Provide.DHT.MaxWorkers must be positive, got %d", maxWorkers)
		}
	}

	// Validate DedicatedPeriodicWorkers
	if !cfg.DHT.DedicatedPeriodicWorkers.IsDefault() {
		workers := cfg.DHT.DedicatedPeriodicWorkers.WithDefault(DefaultProvideDHTDedicatedPeriodicWorkers)
		if workers < 0 {
			return fmt.Errorf("Provide.DHT.DedicatedPeriodicWorkers must be non-negative, got %d", workers)

View on GitHub (pinned to 329838acdf)

Solutions

  1. Add `ipfs config --json Provide.Enabled false` to fully disable providing (old behavior), or `ipfs config --json Provide.Enabled true` to keep ad-hoc providing without the periodic schedule
  2. Alternatively set Provide.DHT.Interval to a positive value if periodic reproviding was not actually meant to be disabled
  3. Restart the daemon after setting Provide.Enabled explicitly

Example fix

// before
"Provide": { "DHT": { "Interval": "0s" } }
// after
"Provide": { "Enabled": false, "DHT": { "Interval": "0s" } }
Defensive patterns

Strategy: validation

Validate before calling

if iv := cfg.Provide.DHT.Interval; !iv.IsDefault() && iv.WithDefault(config.DefaultProvideDHTInterval) == 0 && cfg.Provide.Enabled == config.Default {
	return errors.New("set Provide.Enabled explicitly when DHT.Interval=0")
}

Try / catch

if err := config.ValidateProvideConfig(cfg.Provide); err != nil {
	if strings.Contains(err.Error(), "no longer disables the provide system") {
		cfg.Provide.Enabled = config.False // or True, per intended semantics
	}
	return err
}

Prevention

When it happens

Trigger: Node startup with Provide.DHT.Interval set to exactly 0 while cfg.Provide.Enabled is unset (config.Flag Default), i.e. an operator relying on the old Interval=0 behavior without stating which semantics they want.

Common situations: Upgrading a node whose older config used Interval=0 to disable providing; migration scripts copying the old trick; users following outdated guides.

Related errors


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