cloudflare/cloudflared · error

error copying file %s: %w

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.

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)

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.