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
- Check the wrapped OS error (not exist / permission denied) and create or correct the directory: os.MkdirAll(dir, 0755).
- Fix options.Dir and options.ValueLogDir in badger.Open to point at the real data directory.
- Mount the storage volume before starting the application.
- 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
- Create options.Dir and options.ValueLogDir with os.MkdirAll before Open.
- In containers/k8s, add readiness checks that the data volume is mounted before starting the app.
- Grant the process user ownership of the data directory at deploy time.
- Keep Dir and ValueLogDir pointing to the same persistent volume (unless deliberately split).
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
- Unable to parse log id.
- ErrEncryptionKeyMismatch
- While setting banned keys: %w
- Cannot find directory %q for read-only open
- Cannot use NewTransactionAt with managedDB=false. Use NewTra
AI-assisted analysis of dgraph-io/badger@2a001d466f (2026-09-05).
Data as JSON: /api/errors/a7602c2d5de0627e.
Report an issue: GitHub.