Multipart upload and the ETag-that-isn't-an-MD5
A multipart object's ETag is a hash of the part hashes with a "-N" suffix, NOT the MD5 of the file — so the same bytes uploaded with a different part size produce a different ETag.
With the index telling the truth and the object stored durably, the last piece of an object's life is the upload itself — and objects too big for one request expose a famous integrity gotcha.
Scene 09
Multipart upload and the ETag-that-isn't-an-MD5
- Watch
- Try it
- Predict
- Capture
A 200 MiB file is sliced into 4 parts. Each uploads in parallel along its own arrow and returns its own ETag into the manifest. Once all four land, the server runs CompleteMultipartUpload and stitches them into one object — whose ETag renders as a hash-of-hashes ending in "-4".
Highlighted lines are the ones running in the diagram right now.
def multipartUpload(file, partSize):uploadId = s3.createMultipartUpload(key)manifest = []for n, chunk in enumerate(slice(file, partSize), 1):# each part >= 5 MiB except the last, partNumber 1..10000etag = s3.uploadPart(uploadId, n, chunk)manifest.append((n, etag)) # (partNumber, ETag)return s3.completeMultipartUpload(uploadId, manifest)
def completeMultipartUpload(uploadId, manifest):parts = sortByPartNumber(manifest) # order, not arrivalstitchIntoObject(parts)if len(parts) == 1 and wasSinglePut(uploadId):objectEtag = md5(object.bytes) # == md5(file)else:joined = concat(md5Binary(p) for p in parts)objectEtag = md5(joined) + "-" + str(len(parts))return objectEtag
Where this sits in Build an S3-style distributed object store
Scene 09 of 12, in the Make it real act — Strong consistency, multipart upload, lifecycle & tiering.. Parallel resumable parts, a completion manifest, and why the object ETag is a hash-of-hashes ending in -N.
Up next. That orphaned-parts cleanup rule is one declarative lifecycle action — and lifecycle rules also drive the bigger cost lever: sliding objects down to cheaper storage as they cool.
All 12 scenes in Build an S3-style distributed object store · Every curriculum