{"record":{"id":"3c1605612d4fff7b","repo":"flipped-aurora/gin-vue-admin","slug":"function-file-open-failed-err-3c1605","errorCode":null,"errorMessage":"function file.Open() failed, err:","messagePattern":"function file\\.Open\\(\\) failed, err:","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/utils/upload/aws_s3.go","lineNumber":43,"sourceCode":"//@object: *AwsS3\n//@function: UploadFile\n//@description: Upload file to Aws S3 using aws-sdk-go-v2. See https://docs.aws.amazon.com/sdk-for-go/v2/developer-guide/s3-example-basic-bucket-operations.html\n//@param: file *multipart.FileHeader\n//@return: string, string, error\n\nfunc (*AwsS3) UploadFile(ctx context.Context, file *multipart.FileHeader) (string, string, error) {\n\tclient, err := newS3Client()\n\tif err != nil {\n\t\treturn \"\", \"\", err\n\t}\n\tuploader := manager.NewUploader(client)\n\n\tfileKey := fmt.Sprintf(\"%d%s\", time.Now().Unix(), file.Filename)\n\tfilename := global.GVA_CONFIG.AwsS3.PathPrefix + \"/\" + fileKey\n\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\t_, err = uploader.Upload(context.TODO(), &s3.PutObjectInput{\n\t\tBucket:      aws.String(global.GVA_CONFIG.AwsS3.Bucket),\n\t\tKey:         aws.String(filename),\n\t\tBody:        f,\n\t\tContentType: aws.String(file.Header.Get(\"Content-Type\")),\n\t})\n\tif err != nil {\n\t\tlogger.WithCtx(ctx).Mod(\"upload\").Err(err).Error(\"function uploader.Upload() failed\")\n\t\treturn \"\", \"\", err\n\t}\n\n\treturn global.GVA_CONFIG.AwsS3.BaseURL + \"/\" + filename, fileKey, nil\n}\n\n//@author: [WqyJh](https://github.com/WqyJh)","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/utils/upload/aws_s3.go#L25-L61","documentation":"Wraps the error from multipart.File's Open() (the *multipart.FileHeader.Open call) in the AwsS3 UploadFile implementation. file.Open() reads the uploaded part into memory or a temp file; it fails only when the multipart stream is broken, truncated, or the temp file cannot be created. The wrapper logs it with the upload module logger and returns it to the Service layer.","triggerScenarios":"Calling UploadFile with a *multipart.FileHeader whose underlying request body was already consumed or aborted mid-stream, the client disconnected during upload, the uploaded part exceeds memory limits and the OS refuses to create a spool temp file, or a corrupted multipart request.","commonSituations":"Reverse proxy (nginx) buffering limits aborting large uploads; client timeout canceling the request before the file is fully read; missing server temp dir space / read-only /tmp; handler reading c.Request.Body before the upload util does.","solutions":["Increase nginx/proxy client_max_body_size and request timeouts so large uploads are not truncated mid-stream","Check the server temp directory exists, is writable, and has free space (TMPDIR) for multipart spooling","Ensure no middleware consumed c.Request.Body (e.g. a prior ParseMultipartForm or body-logging middleware) before UploadFile runs","Return a 4xx to the client with retry guidance when the multipart stream is aborted; the client should re-send the file"],"exampleFix":"// before\n// middleware already drained the body\nbody, _ := io.ReadAll(c.Request.Body)\n// after\n// do not consume c.Request.Body before form parsing/upload\nfileHeader, err := c.FormFile(\"file\")\nif err != nil { return err }\n_, _, err = uploadOss.UploadFile(fileHeader)","handlingStrategy":"validation","validationCode":"fh, err := c.FormFile(\"file\")\nif err != nil { return nil, fmt.Errorf(\"multipart part missing or invalid: %w\", err) }\nif fh.Size <= 0 { return nil, errors.New(\"uploaded file is empty\") }\nif fh.Size > maxUploadSize { return nil, fmt.Errorf(\"file exceeds %d bytes\", maxUploadSize) }\nf, err := fh.Open()\nif err == nil { defer f.Close() } // fail before calling the upload util","typeGuard":null,"tryCatchPattern":"url, _, err := s3Store.UploadFile(fileHeader)\nif err != nil {\n    if strings.Contains(err.Error(), \"file.Open() failed\") {\n        return \"\", fmt.Errorf(\"upload stream broken, please retry the upload: %w\", err)\n    }\n    return \"\", err\n}","preventionTips":["Never read/consume c.Request.Body before FormFile/Open in middleware","Set proxy client_max_body_size and timeouts above your largest upload","Monitor /tmp (multipart spool dir) for space and permissions","Return 400-level errors to clients so they retry with a fresh request instead of a corrupted stream"],"tags":["aws-s3","multipart","file-upload","io"],"backgroundTag":"multipart-file-open-failed","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}