ipfs/kubo · error

Provide.DHT.MaxWorkers must be positive, got %d

Error message

Provide.DHT.MaxWorkers must be positive, got %d

What it means

Provide.DHT.MaxWorkers sizes the worker pool for provide operations; zero or negative values would deadlock or make no progress. ValidateProvideConfig requires an explicitly set MaxWorkers to be strictly positive.

Source

Thrown at config/provide.go:239

		// 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)
		}
	}

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

View on GitHub (pinned to 329838acdf)

Solutions

  1. Set Provide.DHT.MaxWorkers to a positive integer (default 16)
  2. To disable providing entirely, remove MaxWorkers and set Provide.Enabled=false instead
  3. Clamp the value in any config-generation script to >= 1

Example fix

// before
"MaxWorkers": 0
// after
"MaxWorkers": 16
Defensive patterns

Strategy: validation

Validate before calling

if mw := cfg.Provide.DHT.MaxWorkers; !mw.IsDefault() && mw.WithDefault(config.DefaultProvideDHTMaxWorkers) <= 0 {
	return errors.New("MaxWorkers must be positive")
}

Try / catch

if err := config.ValidateProvideConfig(cfg.Provide); err != nil {
	if strings.Contains(err.Error(), "MaxWorkers must be positive") {
		cfg.Provide.DHT.MaxWorkers = nil // default 16
	}
	return err
}

Prevention

When it happens

Trigger: Node startup when Provide.DHT.MaxWorkers is explicitly set (non-default) to 0 or a negative integer in the config.

Common situations: Operator setting MaxWorkers to 0 intending to disable providing (the correct switch is Provide.Enabled=false); script-generated config computing a zero worker count from an empty value; sign errors.

Related errors


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