dgraph-io/badger · info

ErrNoRewrite

ErrNoRewrite

Error message

Value log GC attempt didn't result in any cleanup

What it means

ErrNoRewrite is returned by DB.RunValueLogGC when the value log garbage-collection attempt completed but no log file was rewritten, meaning nothing was actually cleaned up. Badger returns it so callers know GC found no reclaimable data rather than silently reporting success. It is a sentinel (errors.Is-comparable) error defined in errors.go.

Source

Thrown at errors.go:55

	ErrDiscardedTxn = stderrors.New("This transaction has been discarded. Create a new one")

	// ErrEmptyKey is returned if an empty key is passed on an update function.
	ErrEmptyKey = stderrors.New("Key cannot be empty")

	// ErrInvalidKey is returned if the key has a special !badger! prefix,
	// reserved for internal usage.
	ErrInvalidKey = stderrors.New("Key is using a reserved !badger! prefix")

	// ErrBannedKey is returned if the read/write key belongs to any banned namespace.
	ErrBannedKey = stderrors.New("Key is using the banned prefix")

	// ErrThresholdZero is returned if threshold is set to zero, and value log GC is called.
	// In such a case, GC can't be run.
	ErrThresholdZero = stderrors.New(
		"Value log GC can't run because threshold is set to zero")

	// ErrNoRewrite is returned if a call for value log GC doesn't result in a log file rewrite.
	ErrNoRewrite = stderrors.New(
		"Value log GC attempt didn't result in any cleanup")

	// ErrRejected is returned if a value log GC is called either while another GC is running, or
	// after DB::Close has been called.
	ErrRejected = stderrors.New("Value log GC request rejected")

	// ErrInvalidRequest is returned if the user request is invalid.
	ErrInvalidRequest = stderrors.New("Invalid request")

	// ErrManagedTxn is returned if the user tries to use an API which isn't
	// allowed due to external management of transactions, when using ManagedDB.
	ErrManagedTxn = stderrors.New(
		"Invalid API request. Not allowed to perform this action using ManagedDB")

	// ErrNamespaceMode is returned if the user tries to use an API which is allowed only when
	// NamespaceOffset is non-negative.
	ErrNamespaceMode = stderrors.New(
		"Invalid API request. Not allowed to perform this action when NamespaceMode is not set.")

View on GitHub (pinned to 2a001d466f)

Solutions

  1. Treat ErrNoRewrite as a normal stop signal, not a failure: break out of your GC loop when it is returned
  2. Reduce GC frequency or lower the discardRatio only if you genuinely expect reclaimable data
  3. Ensure deletes/overwrites actually occur before expecting GC to reclaim space
  4. Verify you are not retrying GC in a tight loop, which wastes I/O

Example fix

// before
if err := db.RunValueLogGC(0.5); err != nil {
	return err
}
// after
if err := db.RunValueLogGC(0.5); err != nil && !errors.Is(err, ErrNoRewrite) {
	return err
}
Defensive patterns

Strategy: type-guard

Validate before calling

if discardRatio <= 0.0 || discardRatio >= 1.0 { return errors.New("discardRatio must be in (0,1)") }

Type guard

func isNoRewrite(err error) bool { return errors.Is(err, ErrNoRewrite) }

Try / catch

if err := db.RunValueLogGC(0.5); err != nil {
	if errors.Is(err, ErrNoRewrite) {
		return nil // nothing to collect
	}
	return err
}

Prevention

When it happens

Trigger: Calling db.RunValueLogGC(discardRatio) when the value log files have no discardable (overwritten/deleted) data above the discardRatio threshold; the GC scans a candidate log file, finds too few valid-sample rewrites, and returns without truncating.

Common situations: Periodic GC jobs polling frequently on a small or append-heavy workload; running GC right after opening the DB before any keys have been overwritten; calling GC repeatedly in a loop where only the first call rewrites a file (tests like db_test.go loop until ErrNoRewrite).

Related errors


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