dgraph-io/badger · error

value log file already marked for deletion fid: %d

Error message

value log file already marked for deletion fid: %d

What it means

Returned by valueLog.rewrite (the GC path that rewrites a value-log file) when the file selected for rewrite is already listed in vlog.filesToBeDeleted. A file in that list has already been logically discarded by a previous GC run, so rewriting it would resurrect dead data; the guard rejects the operation so doRunGC should skip this file and pick another. The fault input is the GC candidate file f, racing or re-enqueueing an already-retired log file.

Source

Thrown at value.go:167

		}
		return nil, err
	}
	crc := y.BytesToU32(crcBuf[:])
	if crc != tee.Sum32() {
		return nil, errTruncate
	}
	e.meta = h.meta
	e.UserMeta = h.userMeta
	e.ExpiresAt = h.expiresAt
	return e, nil
}

func (vlog *valueLog) rewrite(f *logFile) error {
	vlog.filesLock.RLock()
	for _, fid := range vlog.filesToBeDeleted {
		if fid == f.fid {
			vlog.filesLock.RUnlock()
			return fmt.Errorf("value log file already marked for deletion fid: %d", fid)
		}
	}
	maxFid := vlog.maxFid
	y.AssertTruef(f.fid < maxFid, "fid to move: %d. Current max fid: %d", f.fid, maxFid)
	vlog.filesLock.RUnlock()

	vlog.opt.Infof("Rewriting fid: %d", f.fid)

	// Announce that a GC rewrite is in flight and pin the discard threshold to the
	// DB's current max committed version. While active, last-level compaction will
	// not purge any version newer than this point (see levelsController.subcompact),
	// so a tombstone for a key we are about to write back survives to shadow it,
	// preventing the deleted key from being resurrected (#2286). GC is serialized by
	// garbageCh (one rewrite at a time), so this per-DB state is not subject to
	// concurrent rewrites; the clamp is released on every exit path.
	//
	// MaxVersion() (not orc.nextTs()) is used deliberately: in managed mode
	// nextTxnTs is frozen at open time and does not track committed versions, so it

View on GitHub (pinned to 2a001d466f)

Solutions

  1. Treat as a skip condition in GC: catch this error in the doRunGC caller, log it at debug/info, and continue with the next candidate file
  2. Avoid invoking RunValueLogGC concurrently from multiple goroutines against the same directory — serialize GC runs
  3. Do not retry the same file immediately; on the next GC pass the file will have been physically deleted
Defensive patterns

Strategy: try-catch

When it happens

Trigger: Thrown at value.go:167 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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