juicedata/juicefs · error
ks3: UploadPartCopy returned no CopyPartResult for %s part %
Error message
ks3: UploadPartCopy returned no CopyPartResult for %s part %d
What it means
ks3.UploadPartCopy performs a server-side copy for one part of a multipart upload and requires resp.CopyPartResult to be present, since the part's ETag lives there. A 200 response with a nil CopyPartResult is treated as a failed copy and surfaces as "ks3: UploadPartCopy returned no CopyPartResult for %s part %d". Without the ETag the part cannot be validated in CompleteMultipartUpload.
Source
Thrown at pkg/object/ks3.go:316
},
})
return err
}
func (s *ks3) UploadPartCopy(ctx context.Context, key string, uploadID string, num int, srcKey string, off, size int64) (*Part, error) {
resp, err := s.s3.UploadPartCopyWithContext(ctx, &s3.UploadPartCopyInput{
Bucket: aws.String(s.bucket),
CopySource: aws.String(s.bucket + "/" + srcKey),
CopySourceRange: aws.String(fmt.Sprintf("bytes=%d-%d", off, off+size-1)),
Key: aws.String(key),
PartNumber: aws.Long(int64(num)),
UploadID: aws.String(uploadID),
})
if err != nil {
return nil, err
}
if resp.CopyPartResult == nil {
return nil, fmt.Errorf("ks3: UploadPartCopy returned no CopyPartResult for %s part %d", key, num)
}
return &Part{Num: num, ETag: aws.ToString(resp.CopyPartResult.ETag)}, nil
}
func (s *ks3) AbortUpload(ctx context.Context, key string, uploadID string) {
params := &s3.AbortMultipartUploadInput{
Bucket: &s.bucket,
Key: &key,
UploadID: &uploadID,
}
_, _ = s.s3.AbortMultipartUploadWithContext(ctx, params)
}
func (s *ks3) CompleteUpload(ctx context.Context, key string, uploadID string, parts []*Part) error {
var s3Parts []*s3.CompletedPart
for i := range parts {
n := new(int64)
*n = int64(parts[i].Num)View on GitHub (pinned to c9a67b23e8)
Solutions
- Verify the source key exists and is readable at copy time (retry the operation).
- Inspect the raw response with SDK debug logging to see whether CopyPartResult XML was returned but not parsed; update the SDK if so.
- Bypass UploadPartCopy by re-uploading the part data directly via UploadPart if the endpoint doesn't fully support copy.
- If using a proxy/compatible gateway, test against the genuine KS3 endpoint to isolate the culprit.
Example fix
// before _, err := s.UploadPartCopy(ctx, dstKey, uploadID, num, srcKey, 0, size) // nil CopyPartResult from proxy // after // read source and upload directly if copy is unsupported part, err := s.UploadPart(ctx, dstKey, uploadID, num, data)
Defensive patterns
Strategy: try-catch
Validate before calling
if src, err := storage.Head(ctx, srcKey); err != nil || src == nil {
return fmt.Errorf("source %s not available for UploadPartCopy", srcKey)
} Try / catch
part, err := storage.UploadPartCopy(ctx, dstKey, uploadID, num, srcKey, off, size)
if err != nil {
if strings.Contains(err.Error(), "no CopyPartResult") {
// fall back to reading the source and uploading the part directly
return uploadPartDirect(ctx, dstKey, uploadID, num, srcKey, off, size)
}
return err
} Prevention
- Confirm the source object exists immediately before copy.
- Avoid proxies that rewrite/strip S3 response XML.
- Fall back to direct UploadPart for endpoints lacking full UploadPartCopy support.
- Keep the KS3 SDK updated to match the response format.
When it happens
Trigger: UploadPartCopy called where KS3 returns success but with a nil CopyPartResult — source object missing/unreadable server-side with error swallowed, response XML missing CopyPartResult due to a proxy, or SDK deserialization mismatch on the CopyPartResult field.
Common situations: Copying through a proxy that strips response elements; source object deleted between validation and copy; KS3-compatible endpoint not fully implementing UploadPartCopy; SDK version mismatch with the KS3 response format.
Understand the failure class
Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.
Related errors
- ks3: CreateMultipartUpload returned empty UploadID for %s
- create multipart upload failed: %s
- multipart upload error: %s
- multipart upload error: %v
- failed to complete multipart upload: %v
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/5af2d23652e769c7.
Report an issue: GitHub.