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
- When starting the render, pass a webhook secret: renderMediaOnLambda({..., webhook: {url, secret}}).
- Read the exact header name Remotion sends (X-Remotion-Signature) and account for lowercasing by your framework (req.headers is usually lower-case).
- 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
- Always pass a `secret` in the webhook config when starting a render.
- Confirm your proxy/CDN forwards custom X-Remotion-* headers.
- Use lowercased header names when reading (req.headers is case-insensitive but always lowercase).
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
- No 'secret' was provided to validateWebhookSignature().
- No 'body' was provided to validateWebhookSignature().
- Signatures do not match
- Lambda Insights is not supported by AWS in region ${region}.
- Pass --s3-output-provider-endpoint when using S3 output prov
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/5e0d4b85139a9cca.
Report an issue: GitHub.