{"record":{"id":"a3395436d2889f3d","repo":"cloudflare/cloudflared","slug":"error-copying-file-s-w-a33954","errorCode":null,"errorMessage":"error copying file %s:%w","messagePattern":"error copying file (.+?):%w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"diagnostic/log_collector_utils.go","lineNumber":109,"sourceCode":"\t\t\treturn \"\", fmt.Errorf(\"error opening file %s: %w\", file.Name(), err)\n\t\t}\n\t\t_, err = io.Copy(outputHandle, logHandle)\n\t\t_ = logHandle.Close()\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"error copying file %s: %w\", file.Name(), err)\n\t\t}\n\t}\n\n\t// nolint: gosec\n\tlogHandle, err := os.Open(filepath.Join(path, defaultLogFilename))\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"error opening file %s:%w\", defaultLogFilename, err)\n\t}\n\tdefer func() { _ = logHandle.Close() }()\n\n\t_, err = io.Copy(outputHandle, logHandle)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"error copying file %s:%w\", logHandle.Name(), err)\n\t}\n\n\treturn outputHandle.Name(), nil\n}\n","sourceCodeStart":91,"sourceCodeEnd":114,"githubUrl":"https://github.com/cloudflare/cloudflared/blob/2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f/diagnostic/log_collector_utils.go#L91-L114","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check available disk space where the output file is written (df).","Retry the collection; transient I/O errors often resolve.","Verify both source and destination filesystems are healthy (dmesg, fsck) and writable.","Inspect the wrapped *os.PathError/syscall.Errno to determine whether the read or write side failed."],"exampleFix":"// before\nout, err := diagnostic.CopyFilesFromDirectory(ctx, dir)\nif err != nil {\n\tlog.Fatal().Err(err).Msg(\"copy failed\")\n}\n// after\nout, err := diagnostic.CopyFilesFromDirectory(ctx, dir)\nif err != nil {\n\tvar pe *fs.PathError\n\tif errors.As(err, &pe) && errors.Is(pe.Err, syscall.ENOSPC) {\n\t\t// free space or write bundle elsewhere\n\t}\n\treturn fmt.Errorf(\"collect logs: %w\", err)\n}","handlingStrategy":"try-catch","validationCode":"if st, err := os.Stat(outputDir); err != nil || !st.IsDir() {\n\treturn fmt.Errorf(\"output dir unavailable: %w\", err)\n}\n// check free space via syscall.Statfs before writing","typeGuard":null,"tryCatchPattern":"out, err := CopyFilesFromDirectory(ctx, dir)\nvar pe *fs.PathError\nif errors.As(err, &pe) {\n\tswitch {\n\tcase errors.Is(pe.Err, syscall.ENOSPC): // free disk space\n\tcase errors.Is(pe.Err, fs.ErrPermission): // fix write perms\n\t}\n}","preventionTips":["Monitor disk space where diagnostic bundles are written","Avoid rotating/deleting the log file during collection","Keep source and destination on healthy local filesystems","Retry collection once on transient I/O errors"],"tags":["diagnostics","filesystem","io"],"backgroundTag":"file-read-failed","analyzedSha":"2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f","analyzedAt":"2026-09-06T04:14:33.757Z","contentChangedAt":"2026-09-06T04:14:33.757Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}