transloadit/uppy · warning · Error

[s3mini] Missing ETag in uploadPart response headers

Error message

[s3mini] Missing ETag in uploadPart response headers

What it means

The preauth flow is only supported for providers that expose a credentialsURL (an endpoint where Companion can exchange pre-auth tokens for real credentials). If providerOptions[providerName].credentialsURL is not set, Companion responds 501 Not Implemented.

Source

Thrown at packages/@uppy/aws-s3/src/s3-client/CompanionS3.ts:146

      {
        method: 'GET',
        signal,
      },
    )

    const { url }: { url: string } = await response.json()

    const xhr = await this._request({
      url,
      method: 'PUT',
      data,
      onProgress,
      signal,
    })

    const etag = U.sanitizeETag(xhr.getResponseHeader('etag'))
    if (etag == null) {
      throw new Error(
        `${C.ERROR_PREFIX}Missing ETag in uploadPart response headers`,
      )
    }

    return { etag }
  }

  public override async listParts({
    uploadId,
    key,
    signal,
  }: IT.ListPartsParams): Promise<IT.UploadPart[]> {
    if (!uploadId) {
      throw new TypeError(C.ERROR_UPLOAD_ID_REQUIRED)
    }

    const response = await this._fetch(
      `/multipart/${encodeURIComponent(uploadId)}?${new URLSearchParams({ key })}`,

View on GitHub (pinned to 5d4dedd02a)

Solutions

  1. Configure providerOptions[providerName].credentialsURL for the provider in Companion options
  2. Only call preauth for providers that support it
  3. Update Companion if the provider gained preauth support in a newer version

Example fix

// before
companion({ providerOptions: { url: {} } })
// after
companion({ providerOptions: { url: { credentialsURL: 'https://example.com/credentials' } } })
Defensive patterns

Strategy: type-guard

Validate before calling

const supportsPreauth = Boolean(providerOptions[providerName]?.credentialsURL)
if (!supportsPreauth) throw new Error(`${providerName} does not support preauth`)

Type guard

const supportsPreauth = (p: string): boolean =>
  Boolean(providerOptions[p]?.credentialsURL)

Try / catch

try {
  await preauth(provider)
} catch (e) {
  if (e.status === 501) return fallbackToDirectAuth()
  throw e
}

Prevention

When it happens

Trigger: Calling preauth for a provider (e.g. URL/Unsplash-type flows) that does not have a credentialsURL configured in companionOptions for this deployment.

Common situations: Attempting preauth for a provider whose server-side setup was not completed (missing credentialsURL in providerOptions); using a Companion version where the provider does not support pre-auth; assuming all providers support preauth.

Related errors


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