dgraph-io/dgraph · error
can't read log file directory: %s
Error message
can't read log file directory: %s
What it means
Error logged by the log writer (x/log_writer.go) when reading the log file directory (e.g. to enumerate existing/rotated logs) fails. The directory is reported via %s. Fix by verifying the log directory exists and is readable by the process.
Source
Thrown at x/log_writer.go:408
if err != nil {
fmt.Printf("error while managing old log files %+v\n", err)
}
}
// prefixAndExt extracts the filename and extension from a filepath.
// eg. prefixAndExt("/home/foo/file.ext") would return ("file", ".ext").
func prefixAndExt(file string) (prefix, ext string) {
filename := filepath.Base(file)
ext = filepath.Ext(filename)
prefix = filename[:len(filename)-len(ext)]
return prefix, ext
}
func processOldLogFiles(fp string, maxAge int64) ([]string, []string, error) {
dir := filepath.Dir(fp)
files, err := os.ReadDir(dir)
if err != nil {
return nil, nil, fmt.Errorf("can't read log file directory: %s", err)
}
defPrefix, defExt := prefixAndExt(fp)
// check only for old files. Those files have - before the time
defPrefix = defPrefix + "-"
toRemove := make([]string, 0)
toKeep := make([]string, 0)
diff := 24 * time.Hour * time.Duration(maxAge)
cutoff := time.Now().Add(-diff)
for _, f := range files {
if f.IsDir() || // f is directory
!strings.HasPrefix(f.Name(), defPrefix) || // f doesn't start with prefix
!(strings.HasSuffix(f.Name(), defExt) || strings.HasSuffix(f.Name(), defExt+".gz")) {
continue
}
View on GitHub (pinned to 759e242be6)
Solutions
- Recreate the log directory with correct ownership (os.MkdirAll)
- Fix the configured log file path to point at an existing writable directory
- Grant the process user read permission on the directory
- Check mount state (read-only/network volumes) for the log directory
Example fix
// before
s, err := x.Init("/missing-dir/dgraph.log", false)
// after
if err := os.MkdirAll("/missing-dir", 0755); err != nil { log.Fatal(err) }
s, err := x.Init("/missing-dir/dgraph.log", false) Defensive patterns
Strategy: try-catch
Validate before calling
dir := filepath.Dir(logPath)
if st, err := os.Stat(dir); err != nil || !st.IsDir() {
return os.MkdirAll(dir, 0755)
} Try / catch
files, err := processOldLogFiles(fp, maxAge)
if err != nil {
log.Printf("old-log cleanup skipped: %v", err) // non-fatal: log rotation still works
} Prevention
- Never delete the log directory while the process is running
- Ensure the service user can read the log dir
- Use local persistent storage for logs instead of removable mounts
When it happens
Trigger: manageOldLogs runs at Init (and periodically) and reads filepath.Dir(l.FilePath); the directory is missing, unreadable, or lacks permissions.
Common situations: Log directory deleted while the process runs, wrong log path configured, non-root containers lacking read access to /var/log, or NFS/RO mounts.
Related errors
- not able to create new file %v
- can't rename log file: %s
- Unsupported key type: %T
- error while creating debug file: %s
- error while creating temporary directory: %s
AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01).
Data as JSON: /api/errors/14017e622f118c9e.
Report an issue: GitHub.