{"record":{"id":"413d814e1413213b","repo":"juicedata/juicefs","slug":"multipart-upload-error-s","errorCode":null,"errorMessage":"multipart upload error: %s","messagePattern":"multipart upload error: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/objbench.go","lineNumber":1052,"sourceCode":"\t\t\t}\n\t\t\ttotal := 3\n\t\t\tseed := make([]byte, upload.MinPartSize)\n\t\t\tutils.RandRead(seed)\n\t\t\tparts := make([]*object.Part, total)\n\t\t\tcontent := make([][]byte, total)\n\t\t\tfor i := 0; i < total; i++ {\n\t\t\t\tcontent[i] = make([]byte, upload.MinPartSize)\n\t\t\t\tgetMockData(seed, i, &content[i])\n\t\t\t}\n\t\t\tvar eg errgroup.Group\n\t\t\teg.SetLimit(4)\n\t\t\tfor i := 1; i <= total; i++ {\n\t\t\t\tnum := i\n\t\t\t\teg.Go(func() error {\n\t\t\t\t\tvar err error\n\t\t\t\t\tparts[num-1], err = blob.UploadPart(ctx, key, upload.UploadID, num, content[num-1])\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terr = fmt.Errorf(\"multipart upload error: %s\", err)\n\t\t\t\t\t}\n\t\t\t\t\treturn err\n\t\t\t\t})\n\t\t\t}\n\t\t\terr = eg.Wait()\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\t// overwrite the first part\n\t\t\tfirstPartContent := append(seed, seed...)\n\t\t\tif parts[0], err = blob.UploadPart(ctx, key, upload.UploadID, 1, firstPartContent); err != nil {\n\t\t\t\treturn fmt.Errorf(\"multipart upload error: %v\", err)\n\t\t\t}\n\t\t\tcontent[0] = firstPartContent\n\n\t\t\t// overwrite the last part\n\t\t\tlastPartContent := []byte(\"hello\")\n\t\t\tif parts[total-1], err = blob.UploadPart(ctx, key, upload.UploadID, total, lastPartContent); err != nil {","sourceCodeStart":1034,"sourceCodeEnd":1070,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/cmd/objbench.go#L1034-L1070","documentation":"objbench uploads 3 parts concurrently via errgroup; any UploadPart error is rewritten to 'multipart upload error: %s' and returned after eg.Wait(). It means one or more part uploads failed; the original backend error is embedded.","triggerScenarios":"`blob.UploadPart(ctx, key, upload.UploadID, num, content[num-1])` fails for any part during the concurrent multipart test — bad upload ID, part size below MinPartSize, timeout, or throttling.","commonSituations":"Part size smaller than the backend minimum (e.g. <5 MiB on S3); invalid/expired upload ID; concurrent-request throttling or rate limits; network flakiness under parallelism.","solutions":["Inspect the embedded backend error for the failing part number","Ensure part size >= the backend minimum (upload.MinPartSize)","Retry the benchmark in case of transient throttling/timeouts","Verify the UploadID is valid and parts are uploaded before CompleteUpload"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// ensure each part meets the backend minimum size\nif len(content) > 0 && len(content[0]) < upload.MinPartSize { /* parts too small */ }","typeGuard":null,"tryCatchPattern":"parts[num-1], err = blob.UploadPart(ctx, key, upload.UploadID, num, content[num-1])\nif err != nil {\n    // retry transient failures before failing the whole upload\n    parts[num-1], err = blob.UploadPart(ctx, key, upload.UploadID, num, content[num-1])\n    if err != nil { return fmt.Errorf(\"multipart upload error: %s\", err) }\n}","preventionTips":["Keep part sizes >= upload.MinPartSize (e.g. 5 MiB on S3)","AbortUpload on failure to avoid orphaned parts","Watch for throttling when uploading parts concurrently","Verify the UploadID remains valid for the upload duration"],"tags":["object-storage","multipart-upload","concurrency"],"backgroundTag":"api-request-failed","analyzedSha":"c9a67b23e8e08ec23ec331aa6f1675e2319e921c","analyzedAt":"2026-09-06T17:55:48.476Z","contentChangedAt":"2026-09-06T17:55:48.476Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}