dgraph-io/badger · critical
initIndex crashed: %v %s
Error message
initIndex crashed: %v %s
What it means
This message is produced by a deferred recover() handler in Table.initIndex. When opening a table (SST) file panics — typically because the mmap-slice t.Data contains zeros from a truncated, partially-synced, or botched file copy — initIndex converts the panic into this error, appending captured debug buffer contents for diagnosis.
Source
Thrown at table/table.go:349
return nil, err
}
return t, nil
}
func (t *Table) initBiggestAndSmallest() (err error) {
// This defer will help gathering debugging info in case initIndex crashes.
defer func() {
if r := recover(); r != nil {
var debugBuf bytes.Buffer
// Best-effort debug collection: a panic here must not escape and
// re-trigger the fatalpanic we are trying to fix. Setting err inside
// this defer (rather than after the reads below) ensures whatever
// debug info was gathered so far is attached even if one of the
// reads panics.
defer func() {
_ = recover()
err = fmt.Errorf("initIndex crashed: %v\n%s", r, debugBuf.String())
}()
// Get the count of null bytes at the end of file. This is to make sure if there was an
// issue with mmap sync or file copy.
count := 0
for i := len(t.Data) - 1; i >= 0; i-- {
if t.Data[i] != 0 {
break
}
count++
}
fmt.Fprintf(&debugBuf, "\n== Recovering from initIndex crash ==\n")
fmt.Fprintf(&debugBuf, "File Info: [ID: %d, Size: %d, Zeros: %d]\n",
t.id, t.tableSize, count)
fmt.Fprintf(&debugBuf, "isEnrypted: %v ", t.shouldDecrypt())
View on GitHub (pinned to 2a001d466f)
Solutions
- Inspect the debug buffer text after 'crashed:' to identify the exact panic cause
- Delete or move the corrupted table file out of the data directory and reopen the DB
- Re-restore the data directory from a verified backup
- Check for filesystem/disk issues and verify file sizes match the manifest
- Never copy the data directory while the database is running; use DB.Backup/Stream instead
Example fix
// before: manually copying live SST files
cp -r /data/badger /backup/badger
// after: use a consistent snapshot
opt := badger.DefaultOptions("/data/badger").WithReadOnly(true)
db, _ := badger.Open(opt)
defer db.Close()
db.Backup(w, 0) // consistent backup instead of raw file copy Defensive patterns
Strategy: validation
Validate before calling
info, err := os.Stat(tablePath)
if err != nil || info.Size() == 0 {
return fmt.Errorf("table %s is empty/truncated", tablePath)
}
// stop Badger before copying directories; prefer db.Backup over file copies Prevention
- Never copy the data directory while Badger is running
- Use db.Backup/db.Stream for backups instead of raw file copies
- Ensure clean shutdown (db.Close) before host shutdown; handle SIGTERM
- Monitor the debug text after 'crashed:' to find the root panic
When it happens
Trigger: Calling db.Open (or badger.Open) where loading a table file panics inside initIndex; t.Data ends in null bytes because mmap sync failed, the file was copied while being written, or the file was truncated and re-extended with zeros.
Common situations: Copying SST files between machines without stopping Badger; crash/power-loss during mmap sync; restoring data directory from a partial backup; disk full during flush causing zero-padded files.
Related errors
- invalid table size in footer. Data corrupted
- invalid checksum length in footer. Data corrupted
- invalid index length in footer. Data corrupted
- Unsupported compression type
- ErrValueLogSize
AI-assisted analysis of dgraph-io/badger@2a001d466f (2026-09-05).
Data as JSON: /api/errors/1c1006aec7fc9e3b.
Report an issue: GitHub.