transloadit/uppy · error · S3ServiceError
S3 returned ${xhr.status}${serviceCode ? ` – ${serviceCode}`
Error message
S3 returned ${xhr.status}${serviceCode ? ` – ${serviceCode}` : ''} What it means
Thrown by S3mini's request() when the S3 endpoint returns a non-2xx HTTP status that isn't a retryable/auth case. It wraps the status code, an optional parsed S3 service error Code, and the response body into a U.S3ServiceError so callers can inspect status and serviceCode.
Source
Thrown at packages/@uppy/aws-s3/src/s3-client/S3mini.ts:365
shouldRetryCredentials &&
this.getCredentials != null &&
serviceCode != null &&
['ExpiredToken', 'InvalidAccessKeyId'].includes(serviceCode)
) {
this.clearCachedCredentials()
// Retry with fresh credentials
return this.request({
request,
data,
onProgress,
signal,
contentType,
shouldRetryCredentials: false, // prevent infinite recursion
})
}
throw new U.S3ServiceError(
`S3 returned ${xhr.status}${serviceCode ? ` – ${serviceCode}` : ''}`,
xhr.status,
serviceCode,
xhr.responseText,
)
}
throw err
}
}
/** Lists uploaded parts for a multipart upload. */
public override async listParts({
uploadId,
key,
signal,
}: IT.ListPartsParams): Promise<IT.UploadPart[]> {
this._checkKey(key)View on GitHub (pinned to 5d4dedd02a)
Solutions
- Inspect error.status and error.serviceCode (e.g. 'AccessDenied', 'NoSuchBucket', 'AuthorizationHeaderMalformed') to identify the cause
- Verify the endpoint/region and bucket configuration in the S3 mini client options
- Refresh or verify credentials if status is 403
- Retry with backoff on 5xx/503 SlowDown statuses
Example fix
// before
await s3Mini.putObject({ key, body })
// after
try {
await s3Mini.putObject({ key, body })
} catch (err) {
if (err instanceof S3ServiceError && err.status === 503) await retryLater()
else throw err
} Defensive patterns
Strategy: retry
Validate before calling
// Validate config before use
if (!endpoint || !credentials.accessKeyId) throw new Error('S3 client misconfigured') Type guard
function isS3ServiceError(e: unknown): e is S3ServiceError {
return e instanceof Error && 'status' in e && 'serviceCode' in e
} Try / catch
try { await s3.call(...) } catch (e) { if (isS3ServiceError(e) && (e.status === 503 || e.status >= 500)) return backoffRetry(); throw e } Prevention
- Verify endpoint, region, and bucket before starting uploads
- Refresh STS credentials proactively before expiry
- Implement exponential backoff for 5xx/503 SlowDown
When it happens
Trigger: Any S3 REST call (putObject, listParts, completeMultipartUpload, etc.) where xhr.status is an error: 400 (malformed XML/signature), 403 (bad credentials), 404 (wrong endpoint/bucket), 503 (slow down).
Common situations: Misconfigured endpoint URL or region, expired STS credentials, wrong bucket name, SigV4 signing mismatches, S3 rate limiting (503 SlowDown).
Related errors
- ERROR_UPLOAD_ID_REQUIRED
- ${C.ERROR_PREFIX}CompleteMultipartUpload response missing Lo
- ${C.ERROR_PREFIX}Failed to complete multipart upload: ${JSON
- ${C.ERROR_PREFIX}Failed to abort multipart upload: ${String(
- ${C.ERROR_PREFIX}Failed to delete object. HTTP status: ${xhr
AI-assisted analysis of transloadit/uppy@5d4dedd02a (2026-08-28).
Data as JSON: /api/errors/3a11192be5f2ca53.
Report an issue: GitHub.