<@ULVA73B9P> I'm using Prefect 3's `aupload_from_p...
# ask-marvin
n
@Marvin I'm using Prefect 3's
aupload_from_path
function on a S3Block to upload a large file, and I got this boto3 error:
Copy code
An error occurred (InvalidRequest) when calling the CompleteMultipartUpload operation: Invalid Request
Why is that?
m
thought for 257.9 seconds
Short answer: this usually happens when multipart upload was initiated with a checksum or encryption setting that isn’t satisfied/consistent across the parts, and S3 rejects the CompleteMultipartUpload call. The most common culprit I see is passing
ChecksumAlgorithm
to
aupload_from_path
(which uses boto3’s high-level transfer). boto3’s transfer manager does not supply per-part checksums, so if you set
ChecksumAlgorithm
on create, S3 expects matching checksums for each part and then fails completion with “Invalid Request”. What to check - If you passed
ChecksumAlgorithm
(e.g.,
CRC32
,
CRC32C
,
SHA1
,
SHA256
) in your
aupload_from_path(..., **upload_kwargs)
, remove it and retry. - Ensure any server-side encryption settings (SSE-S3, SSE-KMS, SSE-C) are consistent across the whole upload. Mixing/omitting SSE headers between parts can also produce this error. - Don’t pass ACLs that your bucket policy forbids (less common for this specific error, but worth checking). Quick test
Copy code
# Problematic (triggers multipart + checksum expectations S3 enforces, but boto3 transfer won't fulfill)
await s3_block.aupload_from_path(
    from_path="/path/largefile.bin",
    to_path="largefile.bin",
    ChecksumAlgorithm="CRC32C",   # <- remove this
)

# Safer (let boto3 handle multipart without flexible checksums)
await s3_block.aupload_from_path(
    from_path="/path/largefile.bin",
    to_path="largefile.bin",
)
If you must use checksums - For files < 5 GB, avoid multipart and use a single PUT (SDK can calculate the checksum for the body): - Use your own boto3 client call to
put_object
with
ChecksumAlgorithm
set; or - Force single-part by raising the multipart threshold above your file size (the Prefect block’s helper doesn’t expose TransferConfig directly, so a custom boto3 call is usually simpler). - For true multipart with checksums, you’ll need a custom multipart implementation that computes and supplies per-part checksums and the final object checksum—boto3’s high-level transfer does not handle this for you. References - Prefect AWS S3 block docs: prefect-aws S3 docs - AWS CompleteMultipartUpload API: API docs - boto3 S3 Transfer (high-level upload) behavior: boto3 S3 transfer guide If you can share your exact call (the
aupload_from_path
line and any kwargs like
ChecksumAlgorithm
,
ServerSideEncryption
,
SSEKMSKeyId
, etc.), I can confirm the precise cause and best fix.
n
@Marvin I didn't use any checksum
m
thought for 225.2 seconds
Got it — no checksum. The next most common cause for “InvalidRequest” on CompleteMultipartUpload is server-side encryption mismatch, especially when multipart uploads are involved. Likely causes to check - SSE-KMS or SSE-C mismatch - If the bucket has default KMS encryption or you passed `ServerSideEncryption`/`SSEKMSKeyId`/SSE-C headers, those parameters must be identical on InitiateMultipartUpload, every UploadPart, and CompleteMultipartUpload. If they differ or are missing on any step, S3 returns InvalidRequest. - Buckets with default KMS can still fail completion if you initiated with explicit SSE params but didn’t include the same on later calls. - Reference: CompleteMultipartUpload and SSE notes: SSE-KMS, SSE-C - S3-compatible endpoints (MinIO, Wasabi, Cloudflare R2) - Some providers return InvalidRequest if unsupported headers (e.g., ACLs) or certain SSE options are present, or if they require slightly different multipart semantics. If you’re not on AWS S3, try removing
ACL
and any SSE args and test again. - File modified mid-upload or inconsistent parts - If the underlying file changes during the transfer, the part ETags gathered by the transfer manager can be inconsistent and cause completion to fail. - Edge cases - Completing an MPU with zero parts (e.g., a 0-byte file pushed through a multipart path) or out-of-order/missing parts will also lead to a 400. boto3 usually protects you from this, but it can happen with non-AWS endpoints or unusual conditions. What to try next 1) If you’re using any SSE, pass the same params to
aupload_from_path
so they propagate to all steps:
Copy code
await s3_block.aupload_from_path(
    from_path="/path/largefile.bin",
    to_path="largefile.bin",
    ServerSideEncryption="aws:kms",
    SSEKMSKeyId="arn:aws:kms:REGION:ACCOUNT:key/your-key-id"
)
2) If you’re on an S3-compatible service, try removing extra args like ACL/SSE entirely and see if it succeeds. 3) Try a single-part upload (helps isolate SSE/MPU issues). For files under 5 GB:
Copy code
async with s3_block.get_s3_client() as s3:
    with open("/path/largefile.bin", "rb") as f:
        await s3.put_object(
            Bucket=s3_block.bucket_name,
            Key="largefile.bin",
            Body=f
        )
If that works, the issue is specific to multipart. 4) Enable debug logs to see the precise S3 message (often more specific than “Invalid Request”): - Set environment variable
BOTO_CONFIG
or configure logging for `botocore`/`boto3` at DEBUG. The error payload often includes details like “The encryption parameters you provided must match...”. If you can share: - Whether you’re uploading to AWS S3 or another S3-compatible provider - Any
upload_kwargs
you passed (e.g.,
ServerSideEncryption
,
SSEKMSKeyId
,
ACL
) - Bucket default encryption (KMS?) and the file size …I can pinpoint the exact cause and the minimal change to fix it. Refs: - Prefect S3 block docs: prefect-aws S3 docs - AWS API: CompleteMultipartUpload and MPU overview: Multipart upload overview