apache/beam · error · S3ClientError
Param validation failed on part number
Error message
Param validation failed on part number
What it means
FakeS3Client.upload_part raises S3ClientError('Param validation failed on part number', 400) when the request's part_number is not an int or is negative. It stands in for boto3's client-side parameter validation (ParamValidationError) for multipart upload part numbers.
Solutions
- Ensure part numbers are plain Python ints and >= 0 (S3 uses 1-based part numbers, so start at 1)
- Cast: part_number = int(part_number) before building the request
- Add an assert/validate on part_number type and range before calling upload_part
- Fix off-by-one or 0-based indexing logic in the uploader
Example fix
// before
request = messages.UploadPartRequest(upload_id, i, data) # i may be negative or numpy int
// after
part_number = int(i)
if part_number < 1:
raise ValueError(f'invalid part number: {part_number}')
request = messages.UploadPartRequest(upload_id, part_number, data) Defensive patterns
Strategy: validation
Validate before calling
assert isinstance(part_number, int) and not isinstance(part_number, bool) and part_number >= 0, f'bad part number: {part_number!r}' Prevention
- Use 1-based, plain-int part numbers (S3 convention)
- Cast indices with int() before building requests
- Beware numpy integers failing isinstance(x, int)
- Add a unit assertion on part_number range in upload loops
When it happens
Trigger: Calling upload_part with part_number < 0, a bool/float/str/None part_number, or a numpy integer type that fails isinstance(part_number, int).
Common situations: Loop index off-by-one producing negative numbers; part numbers computed from data (0-based vs 1-based confusion); passing a numpy.int64 from array-based code paths.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- All parts but the last must be larger than
- error parsing S3 destination uri
- error parsing S3 source uri
- One or more of the specified parts could not be found
- The specified upload does not exist
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/c19f59bdaf21dd51.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/python/apache_beam/io/aws/clients/s3/fake_client.py:192
src_file = self.get_file(request.src_bucket, request.src_key)
dest_file = FakeFile(
request.dest_bucket, request.dest_key, src_file.contents)
self.add_file(dest_file)
def create_multipart_upload(self, request):
# Create hash of bucket and key
# Store upload_id internally
upload_id = request.bucket + request.object
self.multipart_uploads[upload_id] = {}
return messages.UploadResponse(upload_id)
def upload_part(self, request):
# Save off bytes passed to internal data store
upload_id, part_number = request.upload_id, request.part_number
if part_number < 0 or not isinstance(part_number, int):
raise messages.S3ClientError(
'Param validation failed on part number', 400)
if upload_id not in self.multipart_uploads:
raise messages.S3ClientError('The specified upload does not exist', 404)
self.multipart_uploads[upload_id][part_number] = request.bytes
etag = '"%s"' % ('x' * 32)
return messages.UploadPartResponse(etag, part_number)
def complete_multipart_upload(self, request):
MIN_PART_SIZE = 5 * 2**10 # 5 KiB
parts_received = self.multipart_uploads[request.upload_id]
# Check that we got all the parts that they intended to send
part_numbers_to_confirm = set(part['PartNumber'] for part in request.parts)
View on GitHub (pinned to 12126d8942)