Error library

Stripe: Webhook payload must be provided as a string or a Buffer (raw body)

stripe-node throws this when constructEvent() receives a parsed JavaScript object instead of the raw request body. Give the webhook route the unparsed body (a string or Buffer) before any JSON middleware touches it.

Cause: A JSON body parser (e.g. express.json() or req.json()) ran before signature verification.

How to fix it

  1. Mount the webhook route with a raw body parser (express.raw({ type: 'application/json' })) before global express.json().
  2. In Next.js route handlers use await req.text(), not req.json().
  3. Pass that raw body, the Stripe-Signature header and your endpoint secret to constructEvent().
  4. Parse the JSON only after verification succeeds.

Example

Illustrative example, not from a customer project.

- const body = await req.json()
+ const body = await req.text()
  const event = stripe.webhooks.constructEvent(body, sig, secret)

FAQ

Is this the same as 'No signatures found matching the expected signature'?

Related. This one fires when the body is an object; the other when the body, header or secret doesn't match.

Why can't Stripe verify parsed JSON?

The signature is computed over the exact bytes Stripe sent; re-serialized JSON can differ.

Get a $149 diagnosis See pricing Stripe still not live? We take it live at a fixed price.

$149Get a $149 diagnosis