dgraph-io/badger · error
Unable to parse log id.
Error message
Unable to parse log id.
What it means
Thrown by valueLog.populateFilesMap (value.go:506) when a file ending in .vlog exists in the value-log directory but its name before the .vlog suffix is not a valid uint32 (strconv.ParseUint fails). The numeric file ID is required to register the file in filesMap, so Open() aborts.
Source
Thrown at value.go:506
}
func (vlog *valueLog) populateFilesMap() error {
vlog.filesMap = make(map[uint32]*logFile)
files, err := os.ReadDir(vlog.dirPath)
if err != nil {
return errFile(err, vlog.dirPath, "Unable to open log dir.")
}
found := make(map[uint64]struct{})
for _, file := range files {
if !strings.HasSuffix(file.Name(), ".vlog") {
continue
}
fsz := len(file.Name())
fid, err := strconv.ParseUint(file.Name()[:fsz-5], 10, 32)
if err != nil {
return errFile(err, file.Name(), "Unable to parse log id.")
}
if _, ok := found[fid]; ok {
return errFile(err, file.Name(), "Duplicate file found. Please delete one.")
}
found[fid] = struct{}{}
lf := &logFile{
fid: uint32(fid),
path: vlog.fpath(uint32(fid)),
registry: vlog.db.registry,
}
vlog.filesMap[uint32(fid)] = lf
if vlog.maxFid < uint32(fid) {
vlog.maxFid = uint32(fid)
}
}
return nil
}View on GitHub (pinned to 2a001d466f)
Solutions
- List the vlog dir and rename or remove the offending non-numeric .vlog file (keeping only valid '<uint32>.vlog' names).
- Restore the original file name from backup if it was accidentally renamed.
- If the id exceeds uint32, the file was created outside badger's scheme — move it out of the directory and confirm with backups that no valid data is lost.
- Check for hidden characters/whitespace in filenames (ls | cat -A) and correct them.
Example fix
// before $ ls vlogdir badger-manual-copy.vlog 3.vlog // after $ mv vlogdir/badger-manual-copy.vlog /tmp/ # remove/rename invalid file $ ls vlogdir 3.vlog
Defensive patterns
Strategy: validation
Validate before calling
// scan vlog dir for non-numeric *.vlog names before opening badger
func validateVlogNames(dir string) error {
files, err := os.ReadDir(dir)
if err != nil { return err }
for _, f := range files {
name := f.Name()
if !strings.HasSuffix(name, ".vlog") { continue }
if _, err := strconv.ParseUint(name[:len(name)-5], 10, 32); err != nil {
return fmt.Errorf("invalid vlog filename %q: %w", name, err)
}
}
return nil
} Type guard
func isValidVlogName(name string) bool {
if !strings.HasSuffix(name, ".vlog") { return false }
_, err := strconv.ParseUint(strings.TrimSuffix(name, ".vlog"), 10, 32)
return err == nil
} Try / catch
if err := validateVlogNames(vlogDir); err != nil {
// quarantine the bad file instead of failing Open
os.Rename(filepath.Join(vlogDir, badName), filepath.Join(vlogDir, "quarantine", badName))
}
db, err := badger.Open(opts) Prevention
- Never place arbitrary files ending in .vlog in the badger data directory.
- After restores, validate filenames match '^\d+\.vlog$' before opening.
- Avoid manual renames of vlog files; use badger's documented recovery procedures.
- Watch for tooling (scp, editors) that appends suffixes or spaces to filenames.
When it happens
Trigger: A file like 'abc.vlog', '001.vlog' with stray characters, a file with a trailing space or '.vlog.vlog', or an id exceeding uint32 (e.g. '99999999999.vlog') sits in the vlog directory when badger.Open runs.
Common situations: Users manually renaming or creating placeholder .vlog files, rsync/scp artifacts, id field larger than 32 bits from tampering or tooling, tmp files copied in during a botched restore.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Empty value: %+v
- Unable to open log dir.
- Duplicate file found. Please delete one.
- Unable to find fid: %d
- ErrNoRewrite
AI-assisted analysis of dgraph-io/badger@2a001d466f (2026-09-05).
Data as JSON: /api/errors/cc62efb988cf5656.
Report an issue: GitHub.