dgraph-io/badger · error
manifest records table %s at level %d, but MaxLevels is %d
Error message
manifest records table %s at level %d, but MaxLevels is %d
What it means
This build adds a guard in table-open code: the per-level tables slice is sized by opt.MaxLevels, and if the MANIFEST records a table at a level >= MaxLevels, appending would panic — so the code returns this error instead. It means the DB was created/tuned with more levels than the current MaxLevels option allows.
Source
Thrown at levels.go:133
return nil, err
}
if fileID > maxFileID {
maxFileID = fileID
}
go func(fname string, tf TableManifest) {
var rerr error
defer func() {
if r := recover(); r != nil {
rerr = fmt.Errorf("error opening table %s: %v\n%s", fname, r, debug.Stack())
}
throttle.Done(rerr)
numOpened.Add(1)
}()
// tables is sized by opt.MaxLevels, and nothing upstream constrains
// the level recorded in the manifest, so reject an out-of-range level
// here rather than letting the append below panic.
if int(tf.Level) >= len(tables) {
rerr = fmt.Errorf(
"manifest records table %s at level %d, but MaxLevels is %d",
fname, tf.Level, len(tables))
return
}
dk, err := db.registry.DataKey(tf.KeyID)
if err != nil {
rerr = y.Wrapf(err, "Error while reading datakey")
return
}
topt := buildTableOptions(db)
// Explicitly set Compression and DataKey based on how the table was generated.
topt.Compression = tf.Compression
topt.DataKey = dk
mf, err := z.OpenMmapFile(fname, db.opt.getFileFlags(), 0)
if err != nil {
rerr = y.Wrapf(err, "Opening file: %q", fname)
returnView on GitHub (pinned to 2a001d466f)
Solutions
- Raise opts.MaxLevels to at least the level reported in the error message and reopen
- Keep MaxLevels consistent (do not lower it) for a given DB directory across deployments
- If the high-level table is stray, compact/rewrite the DB with the original configuration, then switch options
Example fix
// before opts := badger.DefaultOptions(dir) opts.MaxLevels = 5 // manifest has a table on level 6 // after opts.MaxLevels = 7 // at least one more than the maximum level in MANIFEST
Defensive patterns
Strategy: validation
Validate before calling
// Go: ensure MaxLevels covers manifest before open // parse reported level from the error, or simply set MaxLevels high enough: opts.MaxLevels = 7 // default is 7; never lower it for an existing dir
Try / catch
// Go
db, err := badger.Open(opts)
if err != nil && strings.Contains(err.Error(), "but MaxLevels is") {
var lvl, max int
fmt.Sscanf(err.Error(), "manifest records table %*s at level %d, but MaxLevels is %d", &lvl, &max)
if lvl >= max { opts.MaxLevels = lvl + 1; db, err = badger.Open(opts) }
} Prevention
- Keep MaxLevels (default 7) unchanged for a DB directory across services
- Share one canonical options struct per environment
- Document any option changes when migrating directories
- Prefer defaults unless you have a specific reason
When it happens
Trigger: Opening a DB whose MANIFEST contains a table on level N while opts.MaxLevels <= N — typically after lowering MaxLevels in options, or opening a directory produced by a different configuration/build.
Common situations: Changing badger.DefaultOptions MaxLevels between runs; moving a DB between services with different option files; a manifest written by a fork/patch that allowed higher levels.
Related errors
AI-assisted analysis of dgraph-io/badger@2a001d466f (2026-09-05).
Data as JSON: /api/errors/1f3a5dcb68fe439f.
Report an issue: GitHub.