Initial checklist
Link to runnable example
No response
Steps to reproduce
-
Build a standard @uppy/aws-s3 setup with shouldUseMultipart: () => true
and server endpoints for createMultipartUpload, signPart,
completeMultipartUpload, and abortMultipartUpload.
-
Open the upload page in Safari 26.3.1 on macOS.
-
Drop a handful of JPEG files in the Dashboard widget (we reproduced
with 7 files at 9–12 MB each; also reproduces with a single small PNG).
-
Click Upload.
Same setup, same files, same machine, same network works perfectly in
Chrome. The failure is Safari-specific. The setup worked in Safari prior
to the system auto-update to 26.3.1 around May 8–11, 2026.
Expected behavior
Each file uploads via multipart. The browser PUTs each signed part to S3,
Uppy fires completeMultipartUpload, and the file appears in the bucket.
Actual behavior
For every file, Uppy gets to the part-upload stage and then silently fails.
Confirmed via server-side request logging:
- POST /admin/uploads/create returns 200 (uploadId + key generated)
- POST /admin/uploads/sign-part returns 200 for every part requested —
dozens of successful sign calls per file
- NO POST /admin/uploads/complete ever fires
- Uppy emits upload-error with:
error.message: "Unknown error"
error.name: "Error"
error.cause: null
response.status: null (no HTTP response object was ever constructed)
response.body: ""
- POST /admin/uploads/abort fires to clean up
Captured error object (Safari's WebKit error introspection):
{
"message": "Unknown error",
"source": "{}",
"line": 18,
"column": 14733,
"sourceURL": "https://releases.transloadit.com/uppy/v4.13.0/uppy.min.js",
"stack": "@https://releases.transloadit.com/uppy/v4.13.0/uppy.min.js:18:14733"
}
No cause, no code, no HTTP status — looks like the AwsS3 plugin's fallback
when the underlying XHR aborts before any response is received. response.status
being null (rather than 0, which would suggest a CORS preflight rejection)
suggests the XHR is being torn down at the network layer before any S3
round-trip completes.
What we ruled out before filing:
- S3 bucket CORS — verified correct via independent OPTIONS preflight curl
- Browser cache — hard-refreshed repeatedly
- Safari Intelligent Tracking Prevention — disabled, still fails
- Browser extensions — fails in Safari Private Browsing too
- Third-party CDN script origin — also fails when uppy.min.js is hosted
on the page's own origin (same-origin script, cross-origin PUT to S3)
- Uppy version — fails on both 4.5.0 and 4.13.0
- File specifics — small PNG also fails, not just the production JPEGs
- Project/endpoint state — fails against brand new collections and projects
Working hypothesis: Safari 26 changed something in cross-origin XHR PUT
to *.s3.amazonaws.com — possibly related to Blob.slice() bodies that
multipart uploads use, or a new Privacy Protection rule that silently
aborts the request without surfacing useful error info to JS.
Workaround we're using: routing affected users to Chrome until either
Safari ships a patch or the AwsS3 plugin's retry/error path surfaces
more about what Safari is actually rejecting.
Initial checklist
Link to runnable example
No response
Steps to reproduce
Build a standard @uppy/aws-s3 setup with shouldUseMultipart: () => true
and server endpoints for createMultipartUpload, signPart,
completeMultipartUpload, and abortMultipartUpload.
Open the upload page in Safari 26.3.1 on macOS.
Drop a handful of JPEG files in the Dashboard widget (we reproduced
with 7 files at 9–12 MB each; also reproduces with a single small PNG).
Click Upload.
Same setup, same files, same machine, same network works perfectly in
Chrome. The failure is Safari-specific. The setup worked in Safari prior
to the system auto-update to 26.3.1 around May 8–11, 2026.
Expected behavior
Each file uploads via multipart. The browser PUTs each signed part to S3,
Uppy fires completeMultipartUpload, and the file appears in the bucket.
Actual behavior
For every file, Uppy gets to the part-upload stage and then silently fails.
Confirmed via server-side request logging:
dozens of successful sign calls per file
error.message: "Unknown error"
error.name: "Error"
error.cause: null
response.status: null (no HTTP response object was ever constructed)
response.body: ""
Captured error object (Safari's WebKit error introspection):
{
"message": "Unknown error",
"source": "{}",
"line": 18,
"column": 14733,
"sourceURL": "https://releases.transloadit.com/uppy/v4.13.0/uppy.min.js",
"stack": "@https://releases.transloadit.com/uppy/v4.13.0/uppy.min.js:18:14733"
}
No cause, no code, no HTTP status — looks like the AwsS3 plugin's fallback
when the underlying XHR aborts before any response is received. response.status
being null (rather than 0, which would suggest a CORS preflight rejection)
suggests the XHR is being torn down at the network layer before any S3
round-trip completes.
What we ruled out before filing:
on the page's own origin (same-origin script, cross-origin PUT to S3)
Working hypothesis: Safari 26 changed something in cross-origin XHR PUT
to *.s3.amazonaws.com — possibly related to Blob.slice() bodies that
multipart uploads use, or a new Privacy Protection rule that silently
aborts the request without surfacing useful error info to JS.
Workaround we're using: routing affected users to Chrome until either
Safari ships a patch or the AwsS3 plugin's retry/error path surfaces
more about what Safari is actually rejecting.