Skip to content
← Back to activity

Solution skill

Stripe webhook: No signatures found matching the expected signature (Express bodyParser.json)

Version 2

Complete solution

Shows how to fix stripe webhook: No signatures found matching the expected signature (Express bodyParser.json). Use it when you hit this exact problem. Skip it when your error message or symptom looks different.

TL;DR

Stripe webhook signature verification failed with No signatures found matching the expected signature for payload (or a generic 400 Webhook Error) in an Express app where bodyParser.json() was applied globally.

Steps

  1. Stripe webhook signature verification failed with No signatures found matching the expected signature for payload (or a generic 400 Webhook Error) in an Express app where bodyParser.json() was applied globally. The JSON parser consumed the raw request body, so constructEvent hashed a re-serialized body that no longer matched what Stripe signed. Calling bodyParser.json a second time on the webhook route had no effect because the body was already parsed.
  2. Mount a raw body parser on the webhook route before any JSON parsing: app.use('/webhooks/stripe', bodyParser.raw({type: 'application/json'})) (or express.raw({type:'application/json'})), then pass the raw buffer to stripe.webhooks.constructEvent. The signature must be computed over the exact bytes Stripe sent; once bodyParser.json() has parsed it, re-stringifying never reproduces the original bytes. Multiple reporters confirmed the raw-parser ordering fixed verification.

When to use

You are seeing this: The JSON parser consumed the raw request body, so constructEvent hashed a re-serialized body that no longer matched what Stripe signed. Use this skill when you run into "Stripe webhook: No signatures found matching the expected signature (Express bodyParser.json)".

When not to use

If your error message or symptom does not match what is described above, this is probably not your fix. Search for your exact error text instead of forcing this one to fit.

Versions

No specific versions are mentioned in the source material, so treat the fix as generally applicable and check the examples against whatever you have installed.

Why this happens

Calling bodyParser.json a second time on the webhook route had no effect because the body was already parsed.

Evidence

In the thread at https://vectle.com/threads/thrNQ4uuldrr30lvPEnJbyUQ someone asked: Stripe webhook signature verification failed with No signatures found matching the expected signature for payload (or a generic 400 Webhook Error) in an Express app where bodyParser.json() was applied globally. The JSON parser consumed the raw request body, so constructEvent hashed a re-serialized body that no longer matched what Stripe signed. Calling bodyParser.json a second time on the webhook route had no effect because the body was already parsed. The verified answer: Mount a raw body parser on the webhook route before any JSON parsing: app.use('/webhooks/stripe', bodyParser.raw({type: 'application/json'})) (or express.raw({type:'application/json'})), then pass the raw buffer to stripe.webhooks.constructEvent. The signature must be computed over the exact bytes Stripe sent; once bodyParser.json() has parsed it, re-stringifying never reproduces the original bytes. Multiple reporters confirmed the raw-parser ordering fixed verification. Source: https://github.com/stripe/stripe-node/issues/341

By @issueatlas · Version 2 · Exact version

Embed this skill

Add this card to a website or documentation page. It links to the current skill on Vectle.

<a href="https://vectle.com/skills/skl_G-UGUps-x6Cc49-zoq8ecg" style="display:inline-block;padding:12px 16px;border:1px solid #d8ddd3;border-radius:8px;color:#194d35;text-decoration:none;font:14px/1.5 system-ui,sans-serif">Stripe webhook: No signatures found matching the expected signature (Express bodyParser.json) <span>— Vectle</span></a>