dgraph-io/badger · error

Cannot have 1 compactor. Need at least 2

Error message

Cannot have 1 compactor. Need at least 2

What it means

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.

Source

Thrown at db.go:148

	threshold        *vlogThreshold

	pub        *publisher
	registry   *KeyRegistry
	blockCache *ristretto.Cache[[]byte, *table.Block]
	indexCache *ristretto.Cache[uint64, *fb.TableIndex]
	allocPool  *z.AllocatorPool
}

const (
	kvWriteChCapacity = 1000
)

func checkAndSetOptions(opt *Options) error {
	// It's okay to have zero compactors which will disable all compactions but
	// we cannot have just one compactor otherwise we will end up with all data
	// on level 2.
	if opt.NumCompactors == 1 {
		return errors.New("Cannot have 1 compactor. Need at least 2")
	}

	if opt.InMemory && (opt.Dir != "" || opt.ValueDir != "") {
		return errors.New("Cannot use badger in Disk-less mode with Dir or ValueDir set")
	}
	opt.maxBatchSize = (15 * opt.MemTableSize) / 100
	opt.maxBatchCount = opt.maxBatchSize / int64(skl.MaxNodeSize)

	// This is the maximum value, vlogThreshold can have if dynamic thresholding is enabled.
	opt.maxValueThreshold = math.Min(maxValueThreshold, float64(opt.maxBatchSize))
	if opt.VLogPercentile < 0.0 || opt.VLogPercentile > 1.0 {
		return errors.New("vlogPercentile must be within range of 0.0-1.0")
	}

	// We are limiting opt.ValueThreshold to maxValueThreshold for now.
	if opt.ValueThreshold > maxValueThreshold {
		return fmt.Errorf("Invalid ValueThreshold, must be less or equal to %d",
			maxValueThreshold)

View on GitHub (pinned to 2a001d466f)

Solutions

  1. Set NumCompactors to 0 to fully disable compaction if that was the intent.
  2. Set NumCompactors to 2 or more (default is 4) so compaction works correctly.
  3. If resource reduction was the goal, lower NumLevelZeroTables / NumLevelZeroTablesStall or MemTableSize instead of using 1 compactor.
  4. Wrap badger.Open and surface the options error with context so misconfiguration is reported at startup.

Example fix

// before
opts := badger.DefaultOptions(dir).WithNumCompactors(1)
db, err := badger.Open(opts) // fails: Cannot have 1 compactor
// after
opts := badger.DefaultOptions(dir).WithNumCompactors(0) // disable compaction
// or: .WithNumCompactors(2) // minimum valid value
db, err := badger.Open(opts)
Defensive patterns

Strategy: validation

Validate before calling

if opts.NumCompactors == 1 {
    return errors.New("badger: NumCompactors must be 0 (disabled) or >= 2")
}
db, err := badger.Open(opts)

Type guard

func validCompactorCount(n int) bool {
    return n != 1 // 0 disables compaction; >=2 is required for compaction
}

Try / catch

db, err := badger.Open(opts)
if err != nil {
    if strings.Contains(err.Error(), "Cannot have 1 compactor") {
        return fmt.Errorf("invalid badger config: NumCompactors=%d; use 0 or >=2", opts.NumCompactors)
    }
    return err
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of dgraph-io/badger@2a001d466f (2026-09-05). Data as JSON: /api/errors/411a0a0a375bfe66. Report an issue: GitHub.