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

  1. Inspect the wrapped %v error to identify the backend cause (auth, 404 on upload ID, unsupported).
  2. Re-run the benchmark with fresh credentials and a writable bucket to rule out expiry/permissions.
  3. Verify the backend supports re-uploading an existing part number; if not, treat the case as unsupported (utils.ErrNotSUP) and skip it.
  4. 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

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


AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06). Data as JSON: /api/errors/79ab23d491b124ea. Report an issue: GitHub.