transloadit/uppy · critical · Error
[s3mini] Failed to create multipart upload: ${JSON.stringify
Error message
[s3mini] Failed to create multipart upload: ${JSON.stringify(
parsed,
)} What it means
After POSTing CreateMultipartUpload, s3mini parses the XML response and expects an `<UploadId>` string. If the response parses but contains no valid uploadId (e.g. S3/proxy returned an error document, empty body, or HTML page), this generic Error is thrown with the parsed payload serialized for debugging. It means the request completed but the multipart session was not created.
Source
Thrown at packages/@uppy/aws-s3/src/s3-client/S3mini.ts:239
const parsed = U.parseXml(xhr.responseText) as Record<string, unknown>
if (parsed && typeof parsed === 'object') {
// Check for both cases of InitiateMultipartUploadResult
const uploadResult =
(parsed.initiateMultipartUploadResult as Record<string, unknown>) ||
(parsed.InitiateMultipartUploadResult as Record<string, unknown>)
if (uploadResult && typeof uploadResult === 'object') {
// Check for both cases of uploadId
const uploadId = uploadResult.uploadId || uploadResult.UploadId
if (uploadId && typeof uploadId === 'string') {
return { uploadId, key }
}
}
}
throw new Error(
`${C.ERROR_PREFIX}Failed to create multipart upload: ${JSON.stringify(
parsed,
)}`,
)
}
public override async uploadPart({
key,
uploadId,
data,
partNumber,
onProgress,
signal,
}: IT.UploadPartParams) {
this._validateUploadPartParams(key, uploadId, partNumber)
const { xhr } = await this.request({
request: {View on GitHub (pinned to 5d4dedd02a)
Solutions
- Inspect the JSON.stringify'd payload in the error message — it usually contains the S3 error code (AccessDenied, NoSuchBucket, InvalidAccessKeyId) that identifies the root cause.
- Verify bucket permissions and that the IAM user has s3:PutObject / s3:PutObjectMultipart actions.
- Confirm the endpoint/region pair is correct and the bucket exists.
- If a proxy sits in front of S3, test the same request with curl/awscurl to see the raw XML response.
Example fix
// before
const { uploadId } = await s3.createMultipartUpload({ key }) // throws generic error
// after
try {
const { uploadId } = await s3.createMultipartUpload({ key })
} catch (err) {
console.error('S3 createMultipartUpload failed:', err.message) // inspect parsed XML error code
throw err
} Defensive patterns
Strategy: try-catch
Try / catch
try {
const { uploadId } = await s3.createMultipartUpload({ key })
} catch (err) {
const msg = String(err?.message ?? '')
if (/AccessDenied/.test(msg)) throw new Error('Insufficient S3 permissions for multipart upload')
if (/NoSuchBucket/.test(msg)) throw new Error('Target bucket does not exist')
throw err
} Prevention
- Log the full parsed payload from the error message — it contains the S3 error code.
- Test bucket policy/IAM for s3:PutObject and multipart actions before shipping.
- Verify endpoint+region+bucket triple in staging before production.
When it happens
Trigger: S3 returns a 200-ish or error XML without UploadId: wrong bucket permissions (AccessDenied), nonexistent bucket (NoSuchBucket), a signature mismatch returned as XML, a proxy/gateway returning HTML, or the endpoint pointing at a non-S3 service.
Common situations: Misconfigured credentials or wrong region causing S3 error XML; endpoint pointing to a CDN/gateway that strips the request; bucket name typos; CORS/proxy interference altering responses; S3-compatible backends (MinIO versions) with different XML shapes.
Related errors
- [s3mini] key must be a non-empty string
- [s3mini] uploadId must be a non-empty string
- [s3mini] partNumber must be a positive integer
- [s3mini] fileType must be a string
- [s3mini] Missing ETag in uploadPart response headers
AI-assisted analysis of transloadit/uppy@5d4dedd02a (2026-08-28).
Data as JSON: /api/errors/a992d34a187a2b70.
Report an issue: GitHub.