{"record":{"id":"817ac69a93271383","repo":"dgraph-io/badger","slug":"errtruncateneeded","errorCode":"ErrTruncateNeeded","errorMessage":"Log truncate required to run DB. This might result in data loss","messagePattern":"Log truncate required to run DB\\. This might result in data loss","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"errors.go","lineNumber":89,"sourceCode":"\t// NamespaceOffset is non-negative.\n\tErrNamespaceMode = stderrors.New(\n\t\t\"Invalid API request. Not allowed to perform this action when NamespaceMode is not set.\")\n\n\t// ErrInvalidDump if a data dump made previously cannot be loaded into the database.\n\tErrInvalidDump = stderrors.New(\"Data dump cannot be read\")\n\n\t// ErrZeroBandwidth is returned if the user passes in zero bandwidth for sequence.\n\tErrZeroBandwidth = stderrors.New(\"Bandwidth must be greater than zero\")\n\n\t// ErrWindowsNotSupported is returned when opt.ReadOnly is used on Windows\n\tErrWindowsNotSupported = stderrors.New(\"Read-only mode is not supported on Windows\")\n\n\t// ErrPlan9NotSupported is returned when opt.ReadOnly is used on Plan 9\n\tErrPlan9NotSupported = stderrors.New(\"Read-only mode is not supported on Plan 9\")\n\n\t// ErrTruncateNeeded is returned when the value log gets corrupt, and requires truncation of\n\t// corrupt data to allow Badger to run properly.\n\tErrTruncateNeeded = stderrors.New(\n\t\t\"Log truncate required to run DB. This might result in data loss\")\n\n\t// ErrBlockedWrites is returned if the user called DropAll. During the process of dropping all\n\t// data from Badger, we stop accepting new writes, by returning this error.\n\tErrBlockedWrites = stderrors.New(\"Writes are blocked, possibly due to DropAll or Close\")\n\n\t// ErrNilCallback is returned when subscriber's callback is nil.\n\tErrNilCallback = stderrors.New(\"Callback cannot be nil\")\n\n\t// ErrEncryptionKeyMismatch is returned when the storage key is not\n\t// matched with the key previously given.\n\tErrEncryptionKeyMismatch = stderrors.New(\"Encryption key mismatch\")\n\n\t// ErrInvalidDataKeyID is returned if the datakey id is invalid.\n\tErrInvalidDataKeyID = stderrors.New(\"Invalid datakey id\")\n\n\t// ErrInvalidEncryptionKey is returned if length of encryption keys is invalid.\n\tErrInvalidEncryptionKey = stderrors.New(\"Encryption key's length should be\" +","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/dgraph-io/badger/blob/2a001d466f6b71a917319a1db41f99860e16e269/errors.go#L71-L107","documentation":"ErrTruncateNeeded is returned when the value log (or memtable WAL) is corrupt and Badger requires truncation of the corrupt tail data to run, which may result in data loss. In read-only mode Badger cannot perform the truncation itself, so replay fails (memtable.go:210 wraps it with offset details). Defined in errors.go as a sentinel error.","triggerScenarios":"Opening a DB in ReadOnly mode whose memtable WAL contains records beyond the replay end offset (endOff < wal.size) — memtable.go:210 returns y.Wrapf(ErrTruncateNeeded, ...); generally any detected value-log corruption needing tail truncation.","commonSituations":"Machine crash or power loss leaving a partially written WAL; copying DB files without flush while running; opening a corrupted DB read-only (e.g. for recovery tools) and hitting the truncation requirement.","solutions":["Open the DB in read-write mode once so Badger can truncate the corrupt data automatically","Back up the data directory before allowing truncation, since tail data may be lost","If data loss is unacceptable, run value-log recovery tooling (e.g. bank/restore-like tools) before opening","Investigate why the WAL was truncated/corrupt: unclean shutdown, disk full, or improper file copy"],"exampleFix":"// before\nopts = append(opts, badger.WithReadOnly(true))\ndb, err := badger.Open(opts...) // ErrTruncateNeeded\n// after\n// open read-write once to let badger truncate the corrupt tail\ndb, err := badger.Open(opts) // no WithReadOnly\nif err != nil { return err }\ndb.Close()\n// now safe to open read-only\nopts = append(opts, badger.WithReadOnly(true))\ndb, err = badger.Open(opts...)","handlingStrategy":"try-catch","validationCode":"// pre-check: inspect MANIFEST/WAL tail integrity, or attempt read-write open first on suspected corruption","typeGuard":"func isTruncateNeeded(err error) bool { return errors.Is(err, ErrTruncateNeeded) }","tryCatchPattern":"db, err := badger.Open(opts)\nif errors.Is(err, ErrTruncateNeeded) {\n\t// back up directory, then reopen WITHOUT ReadOnly so badger can truncate\n}","preventionTips":["Back up the DB directory before opening a suspect DB read-only","Use clean shutdown paths and fsync-aware file copying","Monitor for unclean shutdowns and disk-full events","Copy DB files only while the DB is closed or via the Stream/Backup APIs"],"tags":["badger","corruption","wal","truncation","read-only"],"backgroundTag":"wal-truncation-required","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"}