remotion-dev/remotion · error · Error

No webhook signature was provided

Error message

No webhook signature was provided

What it means

Thrown by validateWebhookSignature() when signatureHeader is missing or equals the sentinel 'NO_SECRET_PROVIDED'. Remotion Lambda sends 'NO_SECRET_PROVIDED' as the signature when no webhook secret was configured on the render call, which means the request cannot be authenticated.

Source

Thrown at packages/lambda-client/src/validate-webhook-signature.ts:36

	}

	if (!body) {
		throw new TypeError(
			"No 'body' was provided to validateWebhookSignature().",
		);
	}

	if (typeof require === 'undefined') {
		throw new Error('validateWebhookSignature can only be called from Node.JS');
	}

	const Crypto = require('crypto');

	const hmac = Crypto.createHmac('sha512', secret);
	const signature = `sha512=${hmac.update(JSON.stringify(body)).digest('hex')}`;

	if (!signatureHeader || signatureHeader === 'NO_SECRET_PROVIDED') {
		throw new Error('No webhook signature was provided');
	}

	if (signatureHeader !== signature) {
		throw new Error('Signatures do not match');
	}
};

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. When starting the render, pass a webhook secret: renderMediaOnLambda({..., webhook: {url, secret}}).
  2. Read the exact header name Remotion sends (X-Remotion-Signature) and account for lowercasing by your framework (req.headers is usually lower-case).
  3. If you control both ends, ensure no proxy strips custom headers.

Example fix

// before
await renderMediaOnLambda({..., webhook: {url: 'https://app.example.com/webhook'}}); // no secret

// after
await renderMediaOnLambda({..., webhook: {url: 'https://app.example.com/webhook', secret: process.env.WEBHOOK_SECRET}});
Defensive patterns

Strategy: validation

Validate before calling

// When starting the render:
await renderMediaOnLambda({..., webhook: {url, secret: process.env.WEBHOOK_SECRET}});
// When handling:
const signatureHeader = req.headers['x-remotion-signature'];
if (!signatureHeader || signatureHeader === 'NO_SECRET_PROVIDED') return res.status(401).send('unauthorized');

Type guard

const hasSignature = (h: unknown): h is string => typeof h === 'string' && h.length > 0 && h !== 'NO_SECRET_PROVIDED';

Try / catch

try {
  validateWebhookSignature({secret, body, signatureHeader});
} catch (err) {
  return res.status(401).send('unauthorized');
}

Prevention

When it happens

Trigger: Receiving a webhook from a render that was started without a webhook secret (the default), or reading the wrong header name so signatureHeader comes through as undefined/empty.

Common situations: Forgetting to pass the `webhook` option with a `secret` to renderMediaOnLambda(); a proxy (load balancer, CDN) stripping the X-Remotion-Signature header; checking the wrong header casing.

Related errors


AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12). Data as JSON: /api/errors/5e0d4b85139a9cca. Report an issue: GitHub.