-
Notifications
You must be signed in to change notification settings - Fork 666
Description
Checkboxes for prior research
- I've gone through Developer Guide and API reference
- I've checked AWS Forums and StackOverflow.
- I've searched for previous similar issues and didn't find any solution.
Describe the bug
When using Upload from @aws-sdk/lib-storage with a streaming body of unknown size (no ContentLength), after all data has been written and the stream is ended, upload.done() can never resolve. The multipart upload completes successfully on S3 (all parts uploaded, object is usable), but the promise from done() never settles, so the application hangs until manually stopped.
This is different from #5652 (Upload stuck with empty file readable stream). Our case is large streaming payloads (e.g. 35–45 GB) from a PassThrough (or similar) stream where total size is unknown up front.
Regression Issue
- Select this option if this issue appears to be a regression.
SDK version number
@aws-sdk/client-s3@3.621.0, @aws-sdk/lib-storage@3.490.0 (also observed in same scenario with other 3.x versions).
Which JavaScript Runtime is this issue in?
Node.js
Details of the browser/Node.js/ReactNative version
Node.js 20.x (LTS)
Reproduction Steps
Create a PassThrough (or other readable) stream as the upload body.
Create Upload with { client, params: { Bucket, Key, Body: stream } } — do not set ContentLength (streaming/unknown size).
Start the upload with upload.done() and write a large amount of data to the stream (e.g. tens of GB) over time.
When the export is finished, call stream.end() so the stream closes.
Await upload.done() (e.g. in a “close” or “shutdown” path).
Observed Behavior
The process hangs at the await upload.done() step. No resolve or reject. The object in S3 is complete and correct; only the promise never settles.
Expected Behavior
done() should resolve with CompleteMultipartUploadCommandOutput (or reject with an error) once the stream has ended and the final CompleteMultipartUpload has been sent and responded to.
Possible Solution
Wrapping upload.done() in a timeout (e.g. Promise.race with a timer) so the application does not block indefinitely. This avoids the hang but does not fix the underlying behavior.
Additional Information/Context
We use the recommended pattern: Upload from lib-storage with a stream body for large/streaming uploads.
We do not pass checksums (e.g. ChecksumSHA256).
Occurrence is intermittent; not every large streaming run hangs, but when it does, it is consistently at the same point (after stream end, waiting on done()).