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

  1. Recreate the log directory with correct ownership (os.MkdirAll)
  2. Fix the configured log file path to point at an existing writable directory
  3. Grant the process user read permission on the directory
  4. 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

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


AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01). Data as JSON: /api/errors/14017e622f118c9e. Report an issue: GitHub.