cloudflare/cloudflared · error

creating temporary log file

Error message

creating temporary log file %s: %w

What it means

Wrapped os.Create failure in diagnostic CopyFilesFromDirectory: the temporary merged log file (cloudflared.log in the OS temp dir) that individual rolling logs are concatenated into could not be created, so log collection aborts.

Solutions

  1. Check disk space and write permissions on os.TempDir() (TMPDIR)
  2. Free space or point TMPDIR at a writable location
  3. Re-run the diagnostic collection

Example fix

// before
TMPDIR=/ro/mount cloudflared diagnostic collect
// after
TMPDIR=/var/tmp cloudflared diagnostic collect
Defensive patterns

Strategy: try-catch

Validate before calling

if err := checkWritable(os.TempDir()); err != nil { os.Setenv("TMPDIR", "/var/tmp") }

Try / catch

out, err := diagnostic.CopyFilesFromDirectory(ctx, fs, logDir, logFilename)
if err != nil && strings.Contains(err.Error(), "creating temporary log file") {
	return fmt.Errorf("cannot write temp logs: %w — check disk space/TMPDIR", err)
}

Prevention

When it happens

Trigger: os.Create(filepath.Join(os.TempDir(), logFilename)) fails: /tmp is full, read-only, or the process lacks write permission; TMPDIR points somewhere invalid.

Common situations: Containers with read-only /tmp or tiny tmpfs; restrictive TMPDIR; disk-quota exhaustion during diagnostics.

Understand the failure class

Background: "Permission denied" / "Failed to write" file errors: why a library can't write its files to disk (EACCES, EPERM, ENOSPC) and how to fix them — this error's family across 43 libraries.

Related errors


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

Appendix: source

Thrown at diagnostic/log_collector_utils.go:83

	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 {
			return "", fmt.Errorf("error copying file %s: %w", file.Name(), err)
		}
	}

	// nolint: gosec
	logHandle, err := os.Open(filepath.Join(path, defaultLogFilename))

View on GitHub (pinned to 2253eeeb25)