dgraph-io/badger · error

Unable to open log dir.

Error message

Unable to open log dir.

What it means

Thrown by valueLog.populateFilesMap (value.go:495) when os.ReadDir on the value-log directory fails while opening the database, wrapping the underlying OS error via errFile. The DB cannot enumerate its .vlog files, so Open() aborts.

Source

Thrown at value.go:495

	garbageCh    chan struct{}
	discardStats *discardStats
}

func vlogFilePath(dirPath string, fid uint32) string {
	return fmt.Sprintf("%s%s%06d.vlog", dirPath, string(os.PathSeparator), fid)
}

func (vlog *valueLog) fpath(fid uint32) string {
	return vlogFilePath(vlog.dirPath, fid)
}

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{

View on GitHub (pinned to 2a001d466f)

Solutions

  1. Check the wrapped OS error (not exist / permission denied) and create or correct the directory: os.MkdirAll(dir, 0755).
  2. Fix options.Dir and options.ValueLogDir in badger.Open to point at the real data directory.
  3. Mount the storage volume before starting the application.
  4. Fix directory permissions/ownership for the user running the process (e.g. chown in container).

Example fix

// before
opts := badger.DefaultOptions("/data/badger")
// after: ensure dir exists first
if err := os.MkdirAll("/data/badger", 0o755); err != nil { log.Fatal(err) }
opts := badger.DefaultOptions("/data/badger")
Defensive patterns

Strategy: validation

Validate before calling

dir := "/data/badger"
if fi, err := os.Stat(dir); err != nil {
    if os.IsNotExist(err) { os.MkdirAll(dir, 0o755) } else { log.Fatalf("vlog dir unusable: %v", err) }
} else if !fi.IsDir() {
    log.Fatalf("%s is not a directory", dir)
}

Type guard

func dirIsReadable(path string) bool {
    fi, err := os.Stat(path)
    return err == nil && fi.IsDir()
}

Try / catch

db, err := badger.Open(opts)
if err != nil {
    var pe *fs.PathError
    if errors.As(err, &pe) { log.Fatalf("open %s: %v (check mount/permissions)", pe.Path, pe.Err) }
    return err
}
defer db.Close()

Prevention

When it happens

Trigger: Calling badger.Open with a Dir/ValueLogDir that does not exist, lacks read permission, is on an unmounted volume, or where the path is a file rather than a directory.

Common situations: Wrong path in options.Dir/options.ValueLogDir, volume not mounted at boot in Kubernetes/systemd setups, permissions changed by container user mismatch, directory deleted by cleanup jobs.

Related errors


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