cloudflare/cloudflared · error

error copying file

Error message

error copying file %s: %w

What it means

Wrapped io.Copy failure inside the per-file loop of diagnostic CopyFilesFromDirectory: reading a rolling log file or writing it into the temporary merged log failed mid-copy, so the collected log bundle would be incomplete and the operation aborts.

Solutions

  1. Verify the default log file (cloudflared.log) exists in the directory and is readable
  2. Ensure cloudflared is running/logging so the default log file is created
  3. Re-run the diagnostic after confirming log directory contents (ls -l <path>)

Example fix

// before
collect from /var/log/cloudflared  # cloudflared.log absent
// after
# confirm logging output path first
ls -l /var/log/cloudflared/cloudflared.log || systemctl restart cloudflared
Defensive patterns

Strategy: fallback

Validate before calling

defaultLog := filepath.Join(logDir, "cloudflared.log")
if _, err := os.Stat(defaultLog); err != nil {
	return errors.New("default log file missing; ensure cloudflared is running and logging")
}

Type guard

func defaultLogExists(logDir, name string) bool {
	_, err := os.Stat(filepath.Join(logDir, name))
	return err == nil
}

Try / catch

out, err := diagnostic.CopyFilesFromDirectory(ctx, fs, logDir, logFilename)
if err != nil && strings.Contains(err.Error(), "error opening file") {
	// proceed with whatever partial bundle exists or surface actionable message
}

Prevention

When it happens

Trigger: os.Open(filepath.Join(path, defaultLogFilename)) fails: cloudflared.log (default) missing from the directory, unreadable, or directory contents changed during collection.

Common situations: Log directory exists but the main log file was renamed/rotated away; fresh install where cloudflared never wrote its default log; permission restrictions on the main log.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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

Appendix: source

Thrown at diagnostic/log_collector_utils.go:96

	}

	// 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 {
			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)