From ccc87b575fbcda7e7e5d0297d5441b884aa57b96 Mon Sep 17 00:00:00 2001 From: chrislu Date: Sun, 16 Nov 2025 18:52:26 -0800 Subject: [PATCH] Multipart ETag semantics: conditionally set object-level Md5 for single-chunk uploads only. --- weed/s3api/s3api_object_handlers_put.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/weed/s3api/s3api_object_handlers_put.go b/weed/s3api/s3api_object_handlers_put.go index 6cb72607a..2d5a14d4a 100644 --- a/weed/s3api/s3api_object_handlers_put.go +++ b/weed/s3api/s3api_object_handlers_put.go @@ -444,12 +444,18 @@ func (s3a *S3ApiServer) putToFiler(r *http.Request, uploadUrl string, dataReader Gid: 0, Mime: mimeType, FileSize: uint64(chunkResult.TotalSize), - Md5: md5Sum, // Set MD5 bytes for multipart ETag validation }, Chunks: chunkResult.FileChunks, // All chunks from auto-chunking Extended: make(map[string][]byte), } + // Only set Md5 for single-chunk uploads to preserve proper multipart ETag semantics + // For multi-chunk uploads, leave Md5 empty so getObjectETag computes the AWS-style + // composite format: MD5(concatenation of part MD5s) + "-" + part count + if len(chunkResult.FileChunks) == 1 { + entry.Attributes.Md5 = md5Sum + } + // Set object owner amzAccountId := r.Header.Get(s3_constants.AmzAccountId) if amzAccountId != "" {