remotion-dev/remotion · error

Conditional output uploads are only supported for AWS S3

Error message

Conditional output uploads are only supported for AWS S3

What it means

lambdaWriteFileIfNotExistsImplementation implements conditional uploads (upload only if the object does not already exist) using S3 conditional writes. Conditional writes are an AWS S3 capability; when custom credentials (a non-AWS provider such as S3-compatible storage via customCredentials) are supplied, the necessary S3 semantics cannot be assumed, so the library throws. Use the regular write path in that case.

Source

Thrown at packages/lambda-client/src/write-file.ts:165

		console.warn(err);
		console.warn(`Retrying (${remainingRetries} retries remaining)...`);

		return writeFileWithRetries({
			...params,
			retries: remainingRetries - 1,
		});
	}
};

export const lambdaWriteFileImplementation = (
	params: WriteFileInput<AwsProvider> & {retries?: number},
): Promise<void> => writeFileWithRetries({...params, ifNotExists: false});

export const lambdaWriteFileIfNotExistsImplementation = (
	params: WriteFileInput<AwsProvider>,
): Promise<void> => {
	if (params.customCredentials !== null) {
		throw new Error('Conditional output uploads are only supported for AWS S3');
	}

	return writeFileWithRetries({...params, ifNotExists: true});
};

View on GitHub (pinned to b2f4e34732)

Solutions

  1. Remove customCredentials and use native AWS S3 credentials if conditional uploads are required
  2. Disable the conditional/ifNotExists upload option so the plain write path is used
  3. Delete existing outputs yourself before rendering instead of relying on conditional uploads
  4. Use a unique output key per render to avoid collisions without conditional writes

Example fix

// before
await renderMediaOnLambda({
  ...params,
  customCredentials: {endpoint: 'https://<account>.r2.cloudflarestorage.com'},
  outputIsIfNotExists: true,
});
// after
await renderMediaOnLambda({
  ...params,
  customCredentials: {endpoint: 'https://<account>.r2.cloudflarestorage.com'},
  outputIsIfNotExists: false,
});
Defensive patterns

Strategy: validation

Validate before calling

if (params.customCredentials && params.outputIsIfNotExists) {
  throw new Error('Conditional output uploads require native AWS S3; disable outputIsIfNotExists or drop customCredentials.');
}

Type guard

const supportsConditionalUploads = (p: {customCredentials: unknown}): boolean => p.customCredentials === null;

Try / catch

try {
  await renderMediaOnLambda(params);
} catch (err) {
  if (String(err).includes('Conditional output uploads')) {
    await renderMediaOnLambda({...params, outputIsIfNotExists: false});
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: Calling renderMediaOnLambda() with outputIsIfNotExists/conditional upload enabled while also passing customCredentials (e.g. Cloudflare R2, MinIO, DigitalOcean Spaces), so the ifNotExists implementation sees params.customCredentials !== null.

Common situations: Using S3-compatible object storage (R2/MinIO/Spaces) with custom credentials and expecting conditional-upload protection that only AWS S3 provides; enabling the overwrite-protection option on a non-AWS provider.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of remotion-dev/remotion@b2f4e34732 (2026-09-09). Data as JSON: /api/errors/eeec12a00fa0b395. Report an issue: GitHub.