juicedata/juicefs · error
multipart upload error: %v
Error message
multipart upload error: %v
What it means
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.
Source
Thrown at cmd/objbench.go:1064
for i := 1; i <= total; i++ {
num := i
eg.Go(func() error {
var err error
parts[num-1], err = blob.UploadPart(ctx, key, upload.UploadID, num, content[num-1])
if err != nil {
err = fmt.Errorf("multipart upload error: %s", err)
}
return err
})
}
err = eg.Wait()
if err != nil {
return err
}
// overwrite the first part
firstPartContent := append(seed, seed...)
if parts[0], err = blob.UploadPart(ctx, key, upload.UploadID, 1, firstPartContent); err != nil {
return fmt.Errorf("multipart upload error: %v", err)
}
content[0] = firstPartContent
// overwrite the last part
lastPartContent := []byte("hello")
if parts[total-1], err = blob.UploadPart(ctx, key, upload.UploadID, total, lastPartContent); err != nil {
return fmt.Errorf("multipart upload error: %v", err)
}
content[total-1] = lastPartContent
if err = blob.CompleteUpload(ctx, key, upload.UploadID, parts); err != nil {
return fmt.Errorf("failed to complete multipart upload: %v", err)
}
r, err := blob.Get(ctx, key, 0, -1)
if err != nil {
return fmt.Errorf("failed to get multipart upload file: %v", err)
}
cnt, err := io.ReadAll(r)View on GitHub (pinned to c9a67b23e8)
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.
Example fix
// before
if parts[0], err = blob.UploadPart(ctx, key, upload.UploadID, 1, firstPartContent); err != nil {
return fmt.Errorf("multipart upload error: %v", err)
}
// after
if parts[0], err = blob.UploadPart(ctx, key, upload.UploadID, 1, firstPartContent); err != nil {
if errors.Is(err, utils.ErrNotSUP) {
return utils.ErrNotSUP // skip backend without full multipart support
}
return fmt.Errorf("multipart upload error (part 1 overwrite): %w", err)
} Defensive patterns
Strategy: retry
Validate before calling
// before running the case
if !supportsMultipart(blob) { // probe via CompleteUpload returning utils.ErrNotSUP
return utils.ErrNotSUP
}
if upload.MinPartSize <= 0 {
return errors.New("backend reported invalid MinPartSize")
} Try / catch
if parts[0], err = blob.UploadPart(ctx, key, upload.UploadID, 1, firstPartContent); err != nil {
if errors.Is(err, utils.ErrNotSUP) {
return utils.ErrNotSUP
}
return fmt.Errorf("multipart upload error: %w", err) // inspect wrapped cause
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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).
Understand the failure class
Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.
Related errors
- create multipart upload failed: %s
- failed to complete multipart upload: %v
- ErrNotSUP
- failed to get the first byte:, expect "h", but got %q, error
- failed to get the last byte: expect "o", but got %q, error:
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/79ab23d491b124ea.
Report an issue: GitHub.