Troubleshooting
Stripe webhook signature verification: fixing failures
Stripe signs the raw request body with your endpoint’s signing secret. Verification fails when the body was parsed first, the wrong secret is used, or the timestamp is stale.
Works with Stripe webhook events. Stripe signs each webhook and puts the signature in the Stripe-Signature header. Verification fails for a short, predictable list of reasons.
Why verification fails
- Parsed body instead of raw — Stripe signs the exact raw request body. If a middleware parsed it to JSON and re-serialized, the
bytes differ and the check fails. Read the raw body (e.g.
express.raw(), the Next.js raw request, or the untouched stream) before verifying. - Wrong signing secret — use the endpoint’s own
whsec_…secret from the Stripe dashboard. Each endpoint has its own, and the Stripe CLI’s secret differs from a live endpoint’s. - Timestamp tolerance — the header includes a
t=timestamp; Stripe’s libraries reject signatures outside a tolerance window (default five minutes) to prevent replay. A stale request or a skewed clock trips this.
Still failing? See the general signature mismatch guide. HookWatch captures the exact request bytes and headers Stripe sent, so you can confirm what was actually signed rather than what you think was sent. See Stripe webhooks.
Related
Keep reading
Get started
Start debugging your webhooks.
Point one endpoint at HookWatch, capture a failure, and replay it once it’s fixed. Free during beta.