{"record":{"id":"411e48ade21dce6e","repo":"juicedata/juicefs","slug":"the-content-of-the-multipart-upload-file-is-incorr","errorCode":null,"errorMessage":"the content of the multipart upload file is incorrect","messagePattern":"the content of the multipart upload file is incorrect","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/objbench.go","lineNumber":1087,"sourceCode":"\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)\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\tif !bytes.Equal(cnt, bytes.Join(content, nil)) {\n\t\t\t\treturn fmt.Errorf(\"the content of the multipart upload file is incorrect\")\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\t\treturn utils.ErrNotSUP\n\t})\n\n\tfunFSCase(\"change owner/group\", func() error {\n\t\tif (strings.HasPrefix(blob.String(), \"file://\") || strings.HasPrefix(blob.String(), \"jfs://\")) && os.Getuid() != 0 {\n\t\t\treturn errors.New(\"root required\")\n\t\t}\n\t\tif err := fi.Chown(key, \"nobody\", groupName); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to chown object %s\", err)\n\t\t}\n\t\tif objInfo, err := blob.Head(ctx, key); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to head object %s\", err)\n\t\t} else if info, ok := objInfo.(object.File); ok {\n\t\t\tif info.Owner() != \"nobody\" {\n\t\t\t\treturn fmt.Errorf(\"expect owner nobody but got %s\", info.Owner())","sourceCodeStart":1069,"sourceCodeEnd":1105,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/cmd/objbench.go#L1069-L1105","documentation":"Returned when the content downloaded after the multipart upload does not byte-equal the expected concatenation of all part contents (with part 1 and the last part overwritten). This is a verification failure, not a transport error: the backend assembled or served the multipart object incorrectly, or part numbering/overwrite semantics deviated from S3 (last-write-wins per part number).","triggerScenarios":"bytes.Equal(cnt, bytes.Join(content, nil)) is false: the backend ignored the overwriting UploadPart for part 1 or the last part, kept a stale ETag, concatenated parts out of order, or served a cached/stale version of the object.","commonSituations":"S3-compatible stores with non-conforming multipart semantics (e.g. keeping the first upload of a part number), eventual consistency serving stale data right after complete, caches (CDN) returning the pre-complete object.","solutions":["Confirm the backend honors overwriting an existing part number with the latest upload before complete.","Disable/bypass CDN or read caches when verifying, or wait for propagation.","Compare part-by-part (ETags from CompleteUpload) to locate which part mismatched.","If the store simply doesn't support these semantics, mark the case unsupported (utils.ErrNotSUP) and skip."],"exampleFix":"// before\nif !bytes.Equal(cnt, bytes.Join(content, nil)) {\n\treturn fmt.Errorf(\"the content of the multipart upload file is incorrect\")\n}\n// after\nif !bytes.Equal(cnt, bytes.Join(content, nil)) {\n\treturn fmt.Errorf(\"the content of the multipart upload file is incorrect: got %d bytes, expect %d bytes\", len(cnt), len(bytes.Join(content, nil)))\n}","handlingStrategy":"validation","validationCode":"expected := bytes.Join(content, nil)\nif len(expected) == 0 {\n\treturn errors.New(\"no content assembled for verification\")\n}\n// compare lengths first to localize the mismatch","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Test backend multipart-overwrite semantics before benchmarking","Bypass CDN/cache layers during content verification","Compare per-part ETags to find which part diverged","Skip (ErrNotSUP) backends that don't honor last-write-wins per part number"],"tags":["object-storage","multipart-upload","verification"],"backgroundTag":"checksum-mismatch","analyzedSha":"c9a67b23e8e08ec23ec331aa6f1675e2319e921c","analyzedAt":"2026-09-06T17:55:48.476Z","contentChangedAt":"2026-09-06T17:55:48.476Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}