transloadit/uppy · error · S3NetworkError

NETWORK

NETWORK

Error message

Network error during S3 request

What it means

When the underlying XHR fails at the network layer, s3mini inspects the error's request: if `xhr.status === 0` (request never completed — no HTTP response), it wraps the failure in S3NetworkError with code 'NETWORK'. This distinguishes connectivity/DNS/CORS-blocked requests from actual HTTP error responses (non-2xx) which are handled separately.

Source

Thrown at packages/@uppy/aws-s3/src/s3-client/S3mini.ts:331

        url,
        method: request.method,
        data,
        onProgress,
        signal,
        contentType,
      })

      return { xhr, url }
    } catch (err: unknown) {
      // NetworkError or errors with attached XHR (from onAfterResponse throws)
      if (
        err instanceof Error &&
        'request' in err &&
        err.request instanceof XMLHttpRequest
      ) {
        const xhr = err.request as XMLHttpRequest
        if (xhr.status === 0) {
          throw new U.S3NetworkError(
            'Network error during S3 request',
            'NETWORK',
            err,
          )
        }
        // HTTP errors (non-2xx responses from NetworkError)
        const parsedBody = this._parseErrorXml(
          (name: string) => xhr.getResponseHeader(name),
          xhr.responseText,
        )
        const serviceCode =
          xhr.getResponseHeader('x-amz-error-code') ?? parsedBody.svcCode

        // If expired token error and using getCredentials, clear cache and retry once
        if (
          shouldRetryCredentials &&
          this.getCredentials != null &&
          serviceCode != null &&

View on GitHub (pinned to 5d4dedd02a)

Solutions

  1. Open devtools Network tab: a failed OPTIONS preflight points to CORS config; a failed DNS/connect points to the endpoint/offline.
  2. For CORS, ensure the bucket allows your origin, the methods (PUT/POST/GET), and required headers (content-type, x-amz-*).
  3. Verify the endpoint URL is reachable from the client environment (curl the URL, check TLS/mixed content).
  4. Retry with backoff for transient network drops — S3NetworkError is safe to retry, especially idempotent part uploads.

Example fix

// before
try { await s3.uploadPart(...) } catch (e) { throw e }
// after
try { await s3.uploadPart(...) } catch (e) {
  if (e.code === 'NETWORK') await retryWithBackoff(() => s3.uploadPart(...))
  else throw e
}
Defensive patterns

Strategy: retry

Type guard

const isNetworkError = (e: unknown): e is { code: 'NETWORK' } =>
  typeof e === 'object' && e !== null && (e as any).code === 'NETWORK'

Try / catch

async function uploadWithRetry(fn: () => Promise<unknown>, tries = 3) {
  for (let i = 0; i < tries; i++) {
    try { return await fn() } catch (e) {
      if ((e as any)?.code === 'NETWORK' && i < tries - 1) {
        await new Promise((r) => setTimeout(r, 2 ** i * 500)); continue
      }
      throw e
    }
  }
}

Prevention

When it happens

Trigger: Device offline or connection dropped mid-request; DNS failure for the endpoint; CORS preflight blocked (browser reports status 0); TLS certificate errors; proxy/firewall resetting the connection. Any XHR that terminates without an HTTP status.

Common situations: Browser uploads blocked by missing/incorrect CORS config on the bucket (preflight failure shows as status 0); flaky mobile networks during multipart uploads; corporate proxies blocking S3 domains; wrong endpoint hostname that doesn't resolve; mixed-content (https page → http endpoint).

Related errors


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