Stripe webhook: "No signatures found matching the expected signature for payload"
No signatures found matching the expected signature for payload. Are you passing the raw request body you received from Stripe?
Also appears as (1)
Webhook payload must be provided as a string or a Buffer ... Payload was provided as a parsed JavaScript object instead.
We reproduced the error and confirmed the fix on our own test machine on the date shown. Nightly CI re-runs are not running yet. How we verify.
- Last verified
- Re-test due
- Published
- Fix ID
APP-19
Environment and versions
| os | Debian 13 (container) |
|---|---|
| node | 20.19.2 |
| express | 5.3.0 |
| stripe | 23.0.1 (stripe-node) |
In brief
Stripe signs the raw request bytes, and your server changes them before verification. The full fix gives the exact Express route order and body handling, the secret checks, and our 4-case test table.
Symptom
You added Stripe Checkout to an app built with Cursor, Bolt or Lovable, with a Node/Express or Next.js backend. Payments go through, but your webhook endpoint returns 400, and your logs show one of these:
No signatures found matching the expected signature for payload. Are you passing the raw request body you received from Stripe?
Webhook payload must be provided as a string or a Buffer ... Payload was provided as a parsed JavaScript object instead.
So orders never get marked as paid.
Why it happens
- Stripe signs the exact bytes it sends.
stripe.webhooks.constructEvent()needs those same, untouched bytes, plus the signing secret (whsec_...) for that endpoint. - AI-generated servers usually add
app.use(express.json())at the top. That turns the body into an object before your webhook code sees it:- Passing that object gives the "must be provided as a string or a Buffer" error.
- "Fixing" it with
JSON.stringify(req.body)creates different bytes, which gives "No signatures found".
- A wrong secret gives the same "No signatures found" error (e.g. the Stripe CLI's secret instead of the dashboard endpoint's, or test vs live).
What we could not test
- Real Stripe deliveries, the Stripe CLI (
stripe listen), and test vs live secrets in a real account. - Next.js App Router and Pages Router, Vercel serverless body handling, and other frameworks.
- Proxies that rewrite the body.
The full fix
$4The free part of this page tells you what's wrong. The full fix tells you exactly what to do. It includes:
- Step-by-step fix, safest option first (the full page is 495 words)
- 2 copy-paste blocks of commands, config or code
- How to check it worked
- Our test record from Oct 26, 2026: what we ran and what happened
Launching soon. Checkout isn't open yet; prices may change at launch. Join the waitlist. You can check what you'll get: SHA-256 of the full fix 98c0a7ca9438f66c… (how to check).
Sources
- Stripe docs: resolve webhook signature verification errors
- Stack Overflow: No signatures found matching the expected signature for payload
- Stack Overflow: Webhook payload must be provided as a string or a Buffer
- Stack Overflow: webhook with Stripe and Next.js 13
- Stack Overflow: Stripe webhook error on Next.js / Vercel
- vercel/next.js#49739
How this page was made
Drafted by an AI agent and reproduced on our test machine on Oct 26, 2026. The scripts and logs are in the repro bundle; their file hashes are public on the repro page. Human review: not yet. No warranty: try fixes on a copy or staging environment first. Machine-readable versions: Markdown · JSON.
Found a mistake or a newer version where this breaks? Tell us.