juicedata/juicefs · error
create multipart upload failed: %s
Error message
create multipart upload failed: %s
What it means
objbench's multipart-upload test first checks CompleteUpload returns utils.ErrNotSUP (backend uses built-in multipart). If not, it starts a real multipart upload via CreateMultipartUpload and wraps failures with this message — meaning the backend refused to initiate a multipart upload.
Source
Thrown at cmd/objbench.go:1033
// Copy `/` suffixed object
defer blob.Delete(ctx, "slash_test_file/") //nolint:errcheck
if err := blob.Put(ctx, "slash_test_file/", bytes.NewReader([]byte("1"))); err != nil {
return fmt.Errorf("put `/` suffixed object failed: %s", err)
}
return nil
})
runCase("multipart upload", func(blob object.ObjectStorage) (err error) {
defer func() {
err = warning(err)
}()
key := "multi_test_file"
if err = blob.CompleteUpload(ctx, key, "notExistsUploadId", []*object.Part{}); err != utils.ErrNotSUP {
defer blob.Delete(ctx, key) //nolint:errcheck
upload, err := blob.CreateMultipartUpload(ctx, key)
if err != nil {
return fmt.Errorf("create multipart upload failed: %s", err)
}
total := 3
seed := make([]byte, upload.MinPartSize)
utils.RandRead(seed)
parts := make([]*object.Part, total)
content := make([][]byte, total)
for i := 0; i < total; i++ {
content[i] = make([]byte, upload.MinPartSize)
getMockData(seed, i, &content[i])
}
var eg errgroup.Group
eg.SetLimit(4)
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 {View on GitHub (pinned to c9a67b23e8)
Solutions
- Read the wrapped backend error for the root cause
- If the backend lacks multipart support, its driver should return utils.ErrNotSUP from CreateMultipartUpload
- Grant multipart-upload permissions (e.g. s3:CreateMultipartUpload) on the bucket
- Test with a backend known to support multipart
Example fix
// before
upload, err := blob.CreateMultipartUpload(ctx, key)
if err != nil { return fmt.Errorf("create multipart upload failed: %s", err) }
// after (driver without multipart support)
func (s *store) CreateMultipartUpload(ctx context.Context, key string) (*object.MultipartUpload, error) {
return nil, utils.ErrNotSUP
} Defensive patterns
Strategy: fallback
Validate before calling
if _, err := blob.CreateMultipartUpload(ctx, "probe"); err != nil {
// backend lacks multipart; use single-put path
}
_ = blob.AbortUpload(ctx, "probe", id) // cleanup if created Try / catch
upload, err := blob.CreateMultipartUpload(ctx, key)
if err != nil {
if errors.Is(err, utils.ErrNotSUP) { /* fall back to Put */ }
return fmt.Errorf("create multipart upload failed: %s", err)
} Prevention
- Grant multipart permissions (s3:CreateMultipartUpload etc.)
- Use backends with known multipart support
- Drivers without multipart should return utils.ErrNotSUP
When it happens
Trigger: `blob.CreateMultipartUpload(ctx, "multi_test_file")` returns an error — backend doesn't implement MultipartUpload, lacks permission, or returns an API error.
Common situations: Stores without multipart support that don't properly return ErrNotSUP; missing s3:PutObject/Multipart permissions; restricted endpoints (e.g. some S3-compatible gateways).
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- multipart upload error: %v
- 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/07478b8f8136cdca.
Report an issue: GitHub.