{"record":{"id":"1e74e33d3a267b86","repo":"flipped-aurora/gin-vue-admin","slug":"function-io-copy-failed-err","errorCode":null,"errorMessage":"function io.Copy() failed, err:","messagePattern":"function io\\.Copy\\(\\) failed, err:","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/utils/upload/local.go","lineNumber":69,"sourceCode":"\tf, openError := file.Open() // 读取文件\n\tif openError != nil {\n\t\tlogger.WithCtx(ctx).Mod(\"upload\").Err(openError).Error(\"function file.Open() failed\")\n\t\treturn \"\", \"\", errors.New(\"function file.Open() failed, err:\" + openError.Error())\n\t}\n\tdefer f.Close() // 创建文件 defer 关闭\n\n\tout, createErr := os.Create(p)\n\tif createErr != nil {\n\t\tlogger.WithCtx(ctx).Mod(\"upload\").Err(createErr).Error(\"function os.Create() failed\")\n\n\t\treturn \"\", \"\", errors.New(\"function os.Create() failed, err:\" + createErr.Error())\n\t}\n\tdefer out.Close() // 创建文件 defer 关闭\n\n\t_, copyErr := io.Copy(out, f) // 传输（拷贝）文件\n\tif copyErr != nil {\n\t\tlogger.WithCtx(ctx).Mod(\"upload\").Err(copyErr).Error(\"function io.Copy() failed\")\n\t\treturn \"\", \"\", errors.New(\"function io.Copy() failed, err:\" + copyErr.Error())\n\t}\n\treturn filepath, filename, nil\n}\n\n//@author: [piexlmax](https://github.com/piexlmax)\n//@author: [ccfish86](https://github.com/ccfish86)\n//@author: [SliverHorn](https://github.com/SliverHorn)\n//@object: *Local\n//@function: DeleteFile\n//@description: 删除文件\n//@param: key string\n//@return: error\n\nfunc (l *Local) DeleteFile(ctx context.Context, key string) error {\n\tp, err := l.localPath(ctx, key)\n\tif err != nil {\n\t\treturn err\n\t}","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/utils/upload/local.go#L51-L87","documentation":"This error is returned by Local.UploadFile when io.Copy(out, f) fails while streaming the uploaded multipart file content into the newly created local file. It indicates an I/O failure reading from the multipart source (client disconnect) or writing to the local file (disk full, I/O error). The underlying error is appended to the message.","triggerScenarios":"UploadFile was called, the destination file was created successfully, but copying the body failed: client aborted the upload mid-transfer, network interruption between client and server, disk became full during the write, or the local disk reported an I/O error.","commonSituations":"Large file uploads over unstable mobile connections where the client disconnects; servers with nearly-full disks where small uploads succeed but large ones hit ENOSPC; NFS/CIFS-mounted storage dropping connections.","solutions":["Check the appended OS error: if 'broken pipe'/'unexpected EOF', it is a client-side disconnect — retry from the client or increase client/proxy timeouts.","If 'no space left on device', free disk space or expand the volume; consider rejecting uploads larger than available space up front.","Add a reverse-proxy (nginx) client_max_body_size and timeout configuration aligned with expected upload sizes.","Delete the partially written file if you want to avoid orphaned partials, since the function returns without cleanup."],"exampleFix":"// before\nserver on 99% disk; large upload -> \"function io.Copy() failed, err: write uploads/x.png: no space left on device\"\n// after\n# shell\ndf -h && du -sh /var/log/* | sort -h   # free space or expand volume, then retry the upload","handlingStrategy":"retry","validationCode":"// before upload, check headroom\nfunc hasDiskHeadroom(storePath string, need uint64) (bool, error) {\n    var st syscall.Statfs_t\n    if err := syscall.Statfs(storePath, &st); err != nil {\n        return false, err\n    }\n    return uint64(st.Bavail)*uint64(st.Bsize) > need, nil\n}","typeGuard":null,"tryCatchPattern":"filePath, filename, err := local.UploadFile(ctx, fileHeader)\nif err != nil {\n    if strings.HasPrefix(err.Error(), \"function io.Copy() failed\") {\n        // transient I/O: allow client retry; log the appended OS error to classify\n        return nil // or requeue with backoff\n    }\n    return err\n}","preventionTips":["Set proxy client body-size limits and timeouts to realistic upload sizes.","Alert on disk free space dropping below a threshold (e.g. 10%).","Clean up partial files after failed copies — the library leaves them behind.","Prefer wired/stable connections or chunked uploads for very large files."],"tags":["filesystem","file-upload","io","go"],"backgroundTag":"disk-full-io-error","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}