BuiltSafely

Home/Fixes

Checklists

No signatures found matching the expected signature for payload (Stripe)

Stripe webhook verification failed: wrong endpoint secret, a parsed body, or a bad Stripe-Signature header. Keep the secret server-side.

  • Docs-only
  • Reviewed Oct 2026
  • 2 official sources
Sources Last checked October 19, 2026 · Badge: docs-only (Stripe official docs; we did not call Stripe) · Sources: official docs (linked below) · Educational, not an audit

The fix

Verify the webhook with Stripe's helper using three correct inputs: the raw request body, the Stripe-Signature header, and the matching endpoint secret (whsec_...). Stripe documents this exact error when any of the three is wrong (Stripe: Resolve webhook signature verification errors).

// Node example shape from Stripe's docs — keep the secret in server-only env
const event = stripe.webhooks.constructEvent(
  requestBody,                         // raw UTF-8 body string, not parsed JSON
  request.headers['stripe-signature'],  // full header value
  process.env.STRIPE_WEBHOOK_SECRET     // whsec_... for THIS endpoint
)

Checklist, in the order Stripe recommends:

  1. Endpoint secret. Dashboard endpoints and Stripe CLI (stripe listen) print different secrets. Both start with whsec_, but they are not interchangeable. Open the endpoint in Workbench → Reveal secret, or copy the CLI secret, and confirm your env matches (Stripe: Resolve signature errors).
  2. Raw body. The body must be the exact UTF-8 string Stripe sent. Frameworks that parse JSON, trim whitespace, or reorder keys break the signature. In Express, register the webhook route before express.json() (Stripe: Resolve signature errors).
  3. Signature header. Print it; it should look like t=...,v1=...,v0=... (Stripe: Resolve signature errors).

Only after verification succeeds should you fulfill the event (mark paid, provision access, and so on).

Why it happens

Without verification, anyone who can reach your URL could POST a fake payment_intent.succeeded and trigger side effects. Stripe signs each delivery; your server recomputes the signature with the endpoint secret and compares it (Stripe: Manage webhook endpoints).

The failure message Stripe quotes is:

Webhook signature verification failed. Err: No signatures found matching the expected signature for payload.

The most common cause is the wrong whsec_ secret; the next is a mutated body (Stripe: Resolve signature errors).

What not to do

  • Don't skip signature verification in production.
  • Don't put the webhook signing secret (whsec_...) or your Stripe secret key (sk_...) in frontend code or public env vars. Keep them server-only (same rule as other provider secrets; see secret key in frontend bundle).
  • Don't disable your app's auth or RLS to "make the webhook work." Webhooks are server-to-server; they use the signing secret, not a user's JWT.
  • Don't mix test and live secrets, or CLI and Dashboard secrets.

AI prompt

My Stripe webhook fails with: No signatures found matching the expected signature for payload.
Check that constructEvent (or equivalent) gets: (1) the raw request body, (2) the Stripe-Signature header, (3) the whsec_ secret for this same endpoint (CLI vs Dashboard).
Ensure JSON body parsing middleware runs AFTER the webhook route.
Keep whsec_ and sk_ keys server-only. Do not put them in VITE_ or NEXT_PUBLIC_ vars.
Show changes first and wait for my OK.

How to verify

  1. Send a test event from the Stripe Dashboard (or stripe trigger via the CLI with the CLI secret).
  2. Confirm your endpoint returns 2xx only after constructEvent succeeds.
  3. Confirm a request with a wrong secret or a parsed body is rejected.
  4. Two-account check on your app: after a real (test-mode) payment for user A, user B still cannot access A's paid features. Enforce entitlements on the server, not only in the UI (our pre-launch checklist).

Pre-launch checklist · Secret key in frontend bundle · AI provider key leaked

Your turn

Was it the CLI secret vs Dashboard secret, or a framework that parsed the body first? Tell us which. We'll put that case first next time.

This guide is educational and based on the vendor's public docs as of the review date. Platforms change: check the linked sources. Not a security audit. Disclaimer.

The BuiltSafely weekly

One email a week. What changed, and the one fix that matters.

Platform changes that affect the security of AI-built apps, checked against official docs. Free. Unsubscribe any time.