cloudflare/cloudflared · error
error reading directory %s: %w
Error message
error reading directory %s: %w
What it means
Wrapped os.ReadDir failure in diagnostic CopyFilesFromDirectory: the directory holding cloudflared's rolling log files could not be read (wrong path, missing directory, or permissions), so the diagnostic log-collection bundle cannot be assembled.
Source
Thrown at diagnostic/log_collector_utils.go:77
return nil, fmt.Errorf(
"error waiting from command '%s': %w",
command.String(),
err,
)
}
return NewLogInformation(outputHandle.Name(), true, false), nil
}
func CopyFilesFromDirectory(path string) (string, error) {
const defaultLogFilename = "cloudflared.log"
// rolling logs have as suffix the current date thus
// when iterating the path files they are already in
// chronological order
files, err := os.ReadDir(path)
if err != nil {
return "", fmt.Errorf("error reading directory %s: %w", path, err)
}
// nolint: gosec
outputHandle, err := os.Create(filepath.Join(os.TempDir(), logFilename))
if err != nil {
return "", fmt.Errorf("creating temporary log file %s: %w", logFilename, err)
}
defer func() { _ = outputHandle.Close() }()
for _, file := range files {
// nolint: gosec
logHandle, err := os.Open(filepath.Join(path, file.Name()))
if err != nil {
return "", fmt.Errorf("error opening file %s: %w", file.Name(), err)
}
_, err = io.Copy(outputHandle, logHandle)
_ = logHandle.Close()
if err != nil {View on GitHub (pinned to 2253eeeb25)
Solutions
- Verify the directory path exists and is readable (ls -ld <path>)
- Recreate/point configuration at the correct cloudflared log directory
- Run the diagnostic as a user with permission to read the log directory
Example fix
// before
err := diagnostic.CopyFilesFromDirectory(ctx, fs, unknownPath, ...)
// after
if _, err := os.Stat(logDir); err != nil { fixPath() }
err := diagnostic.CopyFilesFromDirectory(ctx, fs, logDir, ...) Defensive patterns
Strategy: validation
Validate before calling
fi, err := os.Stat(path)
if err != nil { return fmt.Errorf("log dir missing: %w", err) }
if !fi.IsDir() { return fmt.Errorf("%s is not a directory", path) }
if _, err := os.ReadDir(path); err != nil { return err } Type guard
func isReadableDir(path string) bool {
fi, err := os.Stat(path)
return err == nil && fi.IsDir()
} Try / catch
out, err := diagnostic.CopyFilesFromDirectory(ctx, fs, logDir, logFilename)
if err != nil && strings.Contains(err.Error(), "error reading directory") {
// fall back to default log dir or skip
} Prevention
- Resolve the log directory from config before collecting
- Recreate the log dir if cleanup jobs removed it
- Run the collector with read access to the log dir
When it happens
Trigger: os.ReadDir(path) fails during diagnostic log collection: the log directory does not exist, was rotated/deleted, or the process lacks read permission on it.
Common situations: cloudflared log directory moved or cleaned up before 'diagnostic collect' ran; path typo in configuration; running as a user without access to the log dir.
Related errors
- ErrManagedLogNotFound
- create config dir at %s: %w
- creating temporary log file %s: %w
- error opening file %s: %w
- error copying file %s: %w
AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06).
Data as JSON: /api/errors/acbbfc096eaea957.
Report an issue: GitHub.