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

  1. 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.
  2. Verify bucket permissions and that the IAM user has s3:PutObject / s3:PutObjectMultipart actions.
  3. Confirm the endpoint/region pair is correct and the bucket exists.
  4. 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

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


AI-assisted analysis of transloadit/uppy@5d4dedd02a (2026-08-28). Data as JSON: /api/errors/a992d34a187a2b70. Report an issue: GitHub.