{"record":{"id":"5e0d4b85139a9cca","repo":"remotion-dev/remotion","slug":"no-webhook-signature-was-provided","errorCode":null,"errorMessage":"No webhook signature was provided","messagePattern":"No webhook signature was provided","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/lambda-client/src/validate-webhook-signature.ts","lineNumber":36,"sourceCode":"\t}\n\n\tif (!body) {\n\t\tthrow new TypeError(\n\t\t\t\"No 'body' was provided to validateWebhookSignature().\",\n\t\t);\n\t}\n\n\tif (typeof require === 'undefined') {\n\t\tthrow new Error('validateWebhookSignature can only be called from Node.JS');\n\t}\n\n\tconst Crypto = require('crypto');\n\n\tconst hmac = Crypto.createHmac('sha512', secret);\n\tconst signature = `sha512=${hmac.update(JSON.stringify(body)).digest('hex')}`;\n\n\tif (!signatureHeader || signatureHeader === 'NO_SECRET_PROVIDED') {\n\t\tthrow new Error('No webhook signature was provided');\n\t}\n\n\tif (signatureHeader !== signature) {\n\t\tthrow new Error('Signatures do not match');\n\t}\n};\n","sourceCodeStart":18,"sourceCodeEnd":43,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/lambda-client/src/validate-webhook-signature.ts#L18-L43","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nawait renderMediaOnLambda({..., webhook: {url: 'https://app.example.com/webhook'}}); // no secret\n\n// after\nawait renderMediaOnLambda({..., webhook: {url: 'https://app.example.com/webhook', secret: process.env.WEBHOOK_SECRET}});","handlingStrategy":"validation","validationCode":"// When starting the render:\nawait renderMediaOnLambda({..., webhook: {url, secret: process.env.WEBHOOK_SECRET}});\n// When handling:\nconst signatureHeader = req.headers['x-remotion-signature'];\nif (!signatureHeader || signatureHeader === 'NO_SECRET_PROVIDED') return res.status(401).send('unauthorized');","typeGuard":"const hasSignature = (h: unknown): h is string => typeof h === 'string' && h.length > 0 && h !== 'NO_SECRET_PROVIDED';","tryCatchPattern":"try {\n  validateWebhookSignature({secret, body, signatureHeader});\n} catch (err) {\n  return res.status(401).send('unauthorized');\n}","preventionTips":["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)."],"tags":["lambda","webhook","security","configuration"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}