{"record":{"id":"c5c8f6bf6e9ac939","repo":"ipfs/kubo","slug":"provide-dht-keystorebatchsize-must-be-positive-go","errorCode":null,"errorMessage":"Provide.DHT.KeystoreBatchSize must be positive, got %d","messagePattern":"Provide\\.DHT\\.KeystoreBatchSize must be positive, got (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"config/provide.go","lineNumber":271,"sourceCode":"\t\tworkers := cfg.DHT.DedicatedBurstWorkers.WithDefault(DefaultProvideDHTDedicatedBurstWorkers)\n\t\tif workers < 0 {\n\t\t\treturn fmt.Errorf(\"Provide.DHT.DedicatedBurstWorkers must be non-negative, got %d\", workers)\n\t\t}\n\t}\n\n\t// Validate MaxProvideConnsPerWorker\n\tif !cfg.DHT.MaxProvideConnsPerWorker.IsDefault() {\n\t\tconns := cfg.DHT.MaxProvideConnsPerWorker.WithDefault(DefaultProvideDHTMaxProvideConnsPerWorker)\n\t\tif conns <= 0 {\n\t\t\treturn fmt.Errorf(\"Provide.DHT.MaxProvideConnsPerWorker must be positive, got %d\", conns)\n\t\t}\n\t}\n\n\t// Validate KeystoreBatchSize\n\tif !cfg.DHT.KeystoreBatchSize.IsDefault() {\n\t\tbatchSize := cfg.DHT.KeystoreBatchSize.WithDefault(DefaultProvideDHTKeystoreBatchSize)\n\t\tif batchSize <= 0 {\n\t\t\treturn fmt.Errorf(\"Provide.DHT.KeystoreBatchSize must be positive, got %d\", batchSize)\n\t\t}\n\t}\n\n\t// Validate OfflineDelay\n\tif !cfg.DHT.OfflineDelay.IsDefault() {\n\t\tdelay := cfg.DHT.OfflineDelay.WithDefault(DefaultProvideDHTOfflineDelay)\n\t\tif delay < 0 {\n\t\t\treturn fmt.Errorf(\"Provide.DHT.OfflineDelay must be non-negative, got %v\", delay)\n\t\t}\n\t}\n\n\t// Validate SendProviderRecordTimeout\n\tif !cfg.DHT.SendProviderRecordTimeout.IsDefault() {\n\t\ttimeout := cfg.DHT.SendProviderRecordTimeout.WithDefault(DefaultProvideDHTSendProviderRecordTimeout)\n\t\tif timeout <= 0 {\n\t\t\treturn fmt.Errorf(\"Provide.DHT.SendProviderRecordTimeout must be positive, got %v\", timeout)\n\t\t}\n\t}","sourceCodeStart":253,"sourceCodeEnd":289,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/config/provide.go#L253-L289","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Set Provide.DHT.KeystoreBatchSize to a positive integer (e.g. 128) with `ipfs config --json Provide.DHT.KeystoreBatchSize 128`.","Remove the Provide.DHT.KeystoreBatchSize key entirely so the default (DefaultProvideDHTKeystoreBatchSize) applies.","Re-run `ipfs config show` and verify the value is > 0 before restarting the daemon."],"exampleFix":"// before (config.json)\n\"Provide\": { \"DHT\": { \"KeystoreBatchSize\": 0 } }\n// after\n\"Provide\": { \"DHT\": { \"KeystoreBatchSize\": 128 } }","handlingStrategy":"validation","validationCode":"v, err := ipfsCfg.Provide.DHT.KeystoreBatchSize.WithDefault(config.DefaultProvideDHTKeystoreBatchSize)\nif err == nil && v <= 0 {\n    return fmt.Errorf(\"KeystoreBatchSize must be positive, got %d\", v)\n}","typeGuard":null,"tryCatchPattern":"if err := config.ValidateProvideConfig(cfg); err != nil { log.Fatalf(\"invalid provide config: %v\", err) }","preventionTips":["Never set KeystoreBatchSize to 0 or negative to 'disable'; omit the key instead","Run `ipfs config --json` with typed values rather than editing config.json manually","Call ValidateProvideConfig in tests that generate configs"],"tags":["config","go","validation","dht"],"backgroundTag":"invalid-config-value","analyzedSha":"329838acdfafae224582930457efe80aa217afc0","analyzedAt":"2026-09-03T18:30:52.135Z","contentChangedAt":"2026-09-03T18:30:52.135Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}