cloudflare/cloudflared · error
error opening file %s:%w
Error message
error opening file %s:%w
What it means
CopyFilesFromDirectory in the diagnostic package tries to open the tunnel's default log file (cloudflared.log) inside the given directory to copy it into a diagnostic bundle. When os.Open fails, it wraps the underlying OS error (ENOENT, EACCES, etc.) with this message and returns an empty path, aborting log collection. It reflects that the log file could not be read from disk.
Source
Thrown at diagnostic/log_collector_utils.go:103
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 {
return "", fmt.Errorf("error copying file %s: %w", file.Name(), err)
}
}
// nolint: gosec
logHandle, err := os.Open(filepath.Join(path, defaultLogFilename))
if err != nil {
return "", fmt.Errorf("error opening file %s:%w", defaultLogFilename, err)
}
defer func() { _ = logHandle.Close() }()
_, err = io.Copy(outputHandle, logHandle)
if err != nil {
return "", fmt.Errorf("error copying file %s:%w", logHandle.Name(), err)
}
return outputHandle.Name(), nil
}
View on GitHub (pinned to 2253eeeb25)
Solutions
- Verify the log file exists at the expected path before collecting: os.Stat(filepath.Join(path, defaultLogFilename)).
- Check file permissions and ownership; run collection as a user that can read the log directory (or adjust ACLs/SELinux context).
- Pass the correct directory path containing the log file to CopyFilesFromDirectory.
- Handle the wrapped *fs.PathError in the caller to distinguish not-found from permission issues.
Example fix
// before
out, err := CopyFilesFromDirectory(ctx, logDir)
if err != nil {
return err
}
// after
logPath := filepath.Join(logDir, diagnostic.DefaultLogFilename)
if _, err := os.Stat(logPath); errors.Is(err, fs.ErrNotExist) {
// skip log collection, no log file present
return nil
}
out, err := CopyFilesFromDirectory(ctx, logDir)
if err != nil {
return fmt.Errorf("collect logs: %w", err)
} Defensive patterns
Strategy: validation
Validate before calling
logPath := filepath.Join(dir, "cloudflared.log")
if _, err := os.Stat(logPath); err != nil {
if errors.Is(err, fs.ErrNotExist) { /* skip collection */ }
if errors.Is(err, fs.ErrPermission) { /* fix perms or run as root */ }
} Type guard
func logFileReadable(dir, name string) bool {
f, err := os.Open(filepath.Join(dir, name))
if err != nil { return false }
_ = f.Close()
return true
} Try / catch
out, err := CopyFilesFromDirectory(ctx, dir)
var pe *fs.PathError
if errors.As(err, &pe) && errors.Is(pe.Err, fs.ErrNotExist) {
// degrade gracefully: proceed without log file
} Prevention
- Stat the log file before invoking collection
- Run diagnostic collection under an account with read access to the log directory
- Confirm logging was enabled in the tunnel run so the file exists
- Watch for SELinux/AppArmor denials in audit logs
When it happens
Trigger: Calling CopyFilesFromDirectory (directly or via collectLogs) when the log file does not exist at filepath.Join(path, defaultLogFilename), the path points to a directory without the expected file, or the file lacks read permission.
Common situations: Diagnostic collection on a system where cloudflared was never run with logging enabled; log directory rotated/deleted before collection; running under a service account that cannot read the log directory (e.g. /var/log/cloudflared owned by root); SELinux/AppArmor denials.
Understand the failure class
Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.
Related errors
- ErrManagedLogNotFound
- error creating %s: %v
- error writing %s: %v
- error deleting %s: %v
- error reading directory %s: %w
AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06).
Data as JSON: /api/errors/9d71f35dcdc16675.
Report an issue: GitHub.