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

  1. List the vlog dir and rename or remove the offending non-numeric .vlog file (keeping only valid '<uint32>.vlog' names).
  2. Restore the original file name from backup if it was accidentally renamed.
  3. 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.
  4. 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

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

Related errors


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