{"record":{"id":"411a0a0a375bfe66","repo":"dgraph-io/badger","slug":"cannot-have-1-compactor-need-at-least-2","errorCode":null,"errorMessage":"Cannot have 1 compactor. Need at least 2","messagePattern":"Cannot have 1 compactor\\. Need at least 2","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"db.go","lineNumber":148,"sourceCode":"\tthreshold        *vlogThreshold\n\n\tpub        *publisher\n\tregistry   *KeyRegistry\n\tblockCache *ristretto.Cache[[]byte, *table.Block]\n\tindexCache *ristretto.Cache[uint64, *fb.TableIndex]\n\tallocPool  *z.AllocatorPool\n}\n\nconst (\n\tkvWriteChCapacity = 1000\n)\n\nfunc checkAndSetOptions(opt *Options) error {\n\t// It's okay to have zero compactors which will disable all compactions but\n\t// we cannot have just one compactor otherwise we will end up with all data\n\t// on level 2.\n\tif opt.NumCompactors == 1 {\n\t\treturn errors.New(\"Cannot have 1 compactor. Need at least 2\")\n\t}\n\n\tif opt.InMemory && (opt.Dir != \"\" || opt.ValueDir != \"\") {\n\t\treturn errors.New(\"Cannot use badger in Disk-less mode with Dir or ValueDir set\")\n\t}\n\topt.maxBatchSize = (15 * opt.MemTableSize) / 100\n\topt.maxBatchCount = opt.maxBatchSize / int64(skl.MaxNodeSize)\n\n\t// This is the maximum value, vlogThreshold can have if dynamic thresholding is enabled.\n\topt.maxValueThreshold = math.Min(maxValueThreshold, float64(opt.maxBatchSize))\n\tif opt.VLogPercentile < 0.0 || opt.VLogPercentile > 1.0 {\n\t\treturn errors.New(\"vlogPercentile must be within range of 0.0-1.0\")\n\t}\n\n\t// We are limiting opt.ValueThreshold to maxValueThreshold for now.\n\tif opt.ValueThreshold > maxValueThreshold {\n\t\treturn fmt.Errorf(\"Invalid ValueThreshold, must be less or equal to %d\",\n\t\t\tmaxValueThreshold)","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/dgraph-io/badger/blob/2a001d466f6b71a917319a1db41f99860e16e269/db.go#L130-L166","documentation":"This error is raised by checkAndSetOptions (db.go:148), which validates badger.Options during badger.Open. Exactly one compactor is forbidden: with zero compactors compaction is fully disabled, but with a single compactor all data would pile up on one level without being merged down, so the library refuses the configuration. The value is an ad-hoc errors.New string, not a sentinel.","triggerScenarios":"Calling badger.Open (or OpenManaged) with badger.Options{NumCompactors: 1} (or WithNumCompactors(1)) — the option check runs before the DB is created, so Open fails.","commonSituations":"Attempting to reduce memory/CPU by trimming NumCompactors from the default (4) to 1, not realizing 0 disables compaction but 1 is invalid; tuning code copied between badger versions where defaults changed.","solutions":["Set NumCompactors to 0 to fully disable compaction if that was the intent.","Set NumCompactors to 2 or more (default is 4) so compaction works correctly.","If resource reduction was the goal, lower NumLevelZeroTables / NumLevelZeroTablesStall or MemTableSize instead of using 1 compactor.","Wrap badger.Open and surface the options error with context so misconfiguration is reported at startup."],"exampleFix":"// before\nopts := badger.DefaultOptions(dir).WithNumCompactors(1)\ndb, err := badger.Open(opts) // fails: Cannot have 1 compactor\n// after\nopts := badger.DefaultOptions(dir).WithNumCompactors(0) // disable compaction\n// or: .WithNumCompactors(2) // minimum valid value\ndb, err := badger.Open(opts)","handlingStrategy":"validation","validationCode":"if opts.NumCompactors == 1 {\n    return errors.New(\"badger: NumCompactors must be 0 (disabled) or >= 2\")\n}\ndb, err := badger.Open(opts)","typeGuard":"func validCompactorCount(n int) bool {\n    return n != 1 // 0 disables compaction; >=2 is required for compaction\n}","tryCatchPattern":"db, err := badger.Open(opts)\nif err != nil {\n    if strings.Contains(err.Error(), \"Cannot have 1 compactor\") {\n        return fmt.Errorf(\"invalid badger config: NumCompactors=%d; use 0 or >=2\", opts.NumCompactors)\n    }\n    return err\n}","preventionTips":["Validate badger.Options in your config-loading layer before calling Open.","Remember the rule: NumCompactors 0 = compaction off, 1 = invalid, >=2 = compaction on.","Sanity-check startup in tests: Open a throwaway DB with the production options so config errors surface in CI.","For resource tuning, prefer MemTableSize and NumLevelZeroTables over setting NumCompactors to 1."],"tags":["badger","configuration","compaction","options-validation"],"backgroundTag":"invalid-enum-value","analyzedSha":"2a001d466f6b71a917319a1db41f99860e16e269","analyzedAt":"2026-09-05T13:00:02.264Z","contentChangedAt":"2026-09-05T13:00:02.264Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}