cloudflare/cloudflared · error

error copying file %s:%w

Error message

error copying file %s:%w

What it means

After successfully opening the log file, CopyFilesFromDirectory streams its contents into the output bundle file with io.Copy. If the copy fails (read error on the source, write error on the destination, disk full), the error is wrapped with this message and returned, so the diagnostic bundle is incomplete and no output path is produced.

Source

Thrown at diagnostic/log_collector_utils.go:109

			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. Check available disk space where the output file is written (df).
  2. Retry the collection; transient I/O errors often resolve.
  3. Verify both source and destination filesystems are healthy (dmesg, fsck) and writable.
  4. Inspect the wrapped *os.PathError/syscall.Errno to determine whether the read or write side failed.

Example fix

// before
out, err := diagnostic.CopyFilesFromDirectory(ctx, dir)
if err != nil {
	log.Fatal().Err(err).Msg("copy failed")
}
// after
out, err := diagnostic.CopyFilesFromDirectory(ctx, dir)
if err != nil {
	var pe *fs.PathError
	if errors.As(err, &pe) && errors.Is(pe.Err, syscall.ENOSPC) {
		// free space or write bundle elsewhere
	}
	return fmt.Errorf("collect logs: %w", err)
}
Defensive patterns

Strategy: try-catch

Validate before calling

if st, err := os.Stat(outputDir); err != nil || !st.IsDir() {
	return fmt.Errorf("output dir unavailable: %w", err)
}
// check free space via syscall.Statfs before writing

Try / catch

out, err := CopyFilesFromDirectory(ctx, dir)
var pe *fs.PathError
if errors.As(err, &pe) {
	switch {
	case errors.Is(pe.Err, syscall.ENOSPC): // free disk space
	case errors.Is(pe.Err, fs.ErrPermission): // fix write perms
	}
}

Prevention

When it happens

Trigger: io.Copy fails while transferring the log file: source file becomes unreadable/unlinked mid-read, output handle write fails (disk full, quota exceeded, permissions), or an I/O error on the underlying filesystem.

Common situations: Disk-full on the volume where the diagnostic bundle is written; log file rotated/truncated during collection; NFS/network filesystem I/O errors; output file on a different mount than expected.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


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