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

  1. Verify the directory path exists and is readable (ls -ld <path>)
  2. Recreate/point configuration at the correct cloudflared log directory
  3. 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

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


AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06). Data as JSON: /api/errors/acbbfc096eaea957. Report an issue: GitHub.