{"record":{"id":"79ab23d491b124ea","repo":"juicedata/juicefs","slug":"multipart-upload-error-v","errorCode":null,"errorMessage":"multipart upload error: %v","messagePattern":"multipart upload error: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/objbench.go","lineNumber":1064,"sourceCode":"\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 {\n\t\t\t\treturn fmt.Errorf(\"multipart upload error: %v\", err)\n\t\t\t}\n\t\t\tcontent[total-1] = lastPartContent\n\n\t\t\tif err = blob.CompleteUpload(ctx, key, upload.UploadID, parts); err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to complete multipart upload: %v\", err)\n\t\t\t}\n\t\t\tr, err := blob.Get(ctx, key, 0, -1)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to get multipart upload file: %v\", err)\n\t\t\t}\n\t\t\tcnt, err := io.ReadAll(r)","sourceCodeStart":1046,"sourceCodeEnd":1082,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/cmd/objbench.go#L1046-L1082","documentation":"This error is returned by the 'multipart upload' benchmark case in objbench when the follow-up UploadPart call that overwrites part 1 with a larger body (firstPartContent) fails against the object storage backend. It wraps the underlying backend error (network, permissions, unsupported operation, invalid upload ID, etc.). It indicates the backend rejected re-uploading an already-uploaded part number within an active multipart upload session.","triggerScenarios":"Running `juicefs objbench` against a backend whose UploadPart fails when overwriting part 1 after the initial concurrent uploads: the upload session expired/was aborted, the backend does not allow re-uploading an existing part number, credentials lack multipart permissions, or a transient network error occurred during the request.","commonSituations":"Testing against object stores with restricted multipart semantics (e.g. some S3-compatible implementations that reject part re-upload or non-final small parts), expired presigned credentials mid-benchmark, misconfigured endpoint, or backends that don't truly support multipart (ErrNotSUP paths leaking a real error).","solutions":["Inspect the wrapped %v error to identify the backend cause (auth, 404 on upload ID, unsupported).","Re-run the benchmark with fresh credentials and a writable bucket to rule out expiry/permissions.","Verify the backend supports re-uploading an existing part number; if not, treat the case as unsupported (utils.ErrNotSUP) and skip it.","Check network/proxy stability between the client and the endpoint; retry the benchmark."],"exampleFix":"// before\nif parts[0], err = blob.UploadPart(ctx, key, upload.UploadID, 1, firstPartContent); err != nil {\n\treturn fmt.Errorf(\"multipart upload error: %v\", err)\n}\n// after\nif parts[0], err = blob.UploadPart(ctx, key, upload.UploadID, 1, firstPartContent); err != nil {\n\tif errors.Is(err, utils.ErrNotSUP) {\n\t\treturn utils.ErrNotSUP // skip backend without full multipart support\n\t}\n\treturn fmt.Errorf(\"multipart upload error (part 1 overwrite): %w\", err)\n}","handlingStrategy":"retry","validationCode":"// before running the case\nif !supportsMultipart(blob) { // probe via CompleteUpload returning utils.ErrNotSUP\n\treturn utils.ErrNotSUP\n}\nif upload.MinPartSize <= 0 {\n\treturn errors.New(\"backend reported invalid MinPartSize\")\n}","typeGuard":null,"tryCatchPattern":"if parts[0], err = blob.UploadPart(ctx, key, upload.UploadID, 1, firstPartContent); err != nil {\n\tif errors.Is(err, utils.ErrNotSUP) {\n\t\treturn utils.ErrNotSUP\n\t}\n\treturn fmt.Errorf(\"multipart upload error: %w\", err) // inspect wrapped cause\n}","preventionTips":["Use fresh, multipart-capable credentials for benchmarks","Verify the backend allows re-uploading an existing part number","Run benchmarks on a stable network to reduce transient failures","Treat ErrNotSUP as a skip signal for limited backends"],"tags":["object-storage","multipart-upload","benchmark"],"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"}