{"record":{"id":"14017e622f118c9e","repo":"dgraph-io/dgraph","slug":"can-t-read-log-file-directory-s","errorCode":null,"errorMessage":"can't read log file directory: %s","messagePattern":"can't read log file directory: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"x/log_writer.go","lineNumber":408,"sourceCode":"\tif err != nil {\n\t\tfmt.Printf(\"error while managing old log files %+v\\n\", err)\n\t}\n}\n\n// prefixAndExt extracts the filename and extension from a filepath.\n// eg. prefixAndExt(\"/home/foo/file.ext\") would return (\"file\", \".ext\").\nfunc prefixAndExt(file string) (prefix, ext string) {\n\tfilename := filepath.Base(file)\n\text = filepath.Ext(filename)\n\tprefix = filename[:len(filename)-len(ext)]\n\treturn prefix, ext\n}\n\nfunc processOldLogFiles(fp string, maxAge int64) ([]string, []string, error) {\n\tdir := filepath.Dir(fp)\n\tfiles, err := os.ReadDir(dir)\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"can't read log file directory: %s\", err)\n\t}\n\n\tdefPrefix, defExt := prefixAndExt(fp)\n\t// check only for old files. Those files have - before the time\n\tdefPrefix = defPrefix + \"-\"\n\ttoRemove := make([]string, 0)\n\ttoKeep := make([]string, 0)\n\n\tdiff := 24 * time.Hour * time.Duration(maxAge)\n\tcutoff := time.Now().Add(-diff)\n\n\tfor _, f := range files {\n\t\tif f.IsDir() || // f is directory\n\t\t\t!strings.HasPrefix(f.Name(), defPrefix) || // f doesn't start with prefix\n\t\t\t!(strings.HasSuffix(f.Name(), defExt) || strings.HasSuffix(f.Name(), defExt+\".gz\")) {\n\t\t\tcontinue\n\t\t}\n","sourceCodeStart":390,"sourceCodeEnd":426,"githubUrl":"https://github.com/dgraph-io/dgraph/blob/759e242be62c91f8d084da06ad0c8d21256d9c07/x/log_writer.go#L390-L426","documentation":"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.","triggerScenarios":"manageOldLogs runs at Init (and periodically) and reads filepath.Dir(l.FilePath); the directory is missing, unreadable, or lacks permissions.","commonSituations":"Log directory deleted while the process runs, wrong log path configured, non-root containers lacking read access to /var/log, or NFS/RO mounts.","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"],"exampleFix":"// before\ns, err := x.Init(\"/missing-dir/dgraph.log\", false)\n// after\nif err := os.MkdirAll(\"/missing-dir\", 0755); err != nil { log.Fatal(err) }\ns, err := x.Init(\"/missing-dir/dgraph.log\", false)","handlingStrategy":"try-catch","validationCode":"dir := filepath.Dir(logPath)\nif st, err := os.Stat(dir); err != nil || !st.IsDir() {\n  return os.MkdirAll(dir, 0755)\n}","typeGuard":null,"tryCatchPattern":"files, err := processOldLogFiles(fp, maxAge)\nif err != nil {\n  log.Printf(\"old-log cleanup skipped: %v\", err) // non-fatal: log rotation still works\n}","preventionTips":["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"],"tags":["go","logging","filesystem"],"backgroundTag":"log-directory-unreadable","analyzedSha":"759e242be62c91f8d084da06ad0c8d21256d9c07","analyzedAt":"2026-09-01T14:42:12.034Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}