ipfs/kubo · error

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

Error message

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

What it means

ValidateProvideConfig in config/provide.go rejects the config when Provide.DHT.KeystoreBatchSize is explicitly set (non-default) but resolves to zero or a negative number. The keystore batch size controls how many records the DHT provider keystore writes per batch, so a non-positive value would make batching non-functional. The error is returned during config validation before the node starts.

Source

Thrown at config/provide.go:271

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

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

View on GitHub (pinned to 329838acdf)

Solutions

  1. Set Provide.DHT.KeystoreBatchSize to a positive integer (e.g. 128) with `ipfs config --json Provide.DHT.KeystoreBatchSize 128`.
  2. Remove the Provide.DHT.KeystoreBatchSize key entirely so the default (DefaultProvideDHTKeystoreBatchSize) applies.
  3. Re-run `ipfs config show` and verify the value is > 0 before restarting the daemon.

Example fix

// before (config.json)
"Provide": { "DHT": { "KeystoreBatchSize": 0 } }
// after
"Provide": { "DHT": { "KeystoreBatchSize": 128 } }
Defensive patterns

Strategy: validation

Validate before calling

v, err := ipfsCfg.Provide.DHT.KeystoreBatchSize.WithDefault(config.DefaultProvideDHTKeystoreBatchSize)
if err == nil && v <= 0 {
    return fmt.Errorf("KeystoreBatchSize must be positive, got %d", v)
}

Try / catch

if err := config.ValidateProvideConfig(cfg); err != nil { log.Fatalf("invalid provide config: %v", err) }

Prevention

When it happens

Trigger: Setting Provide.DHT.KeystoreBatchSize in the config to 0 or a negative integer (e.g. via `ipfs config --json Provide.DHT.KeystoreBatchSize 0`) and then initializing/starting the node or calling the validation path used by IPFS node construction.

Common situations: Typing 0 instead of a real batch size, interpreting the docs to mean 'disable batching' by setting 0, or copying config snippets that use -1 as a sentinel.

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