Start by checking the exact raw request body your server received. JSON that looks identical after parsing and printing again may have different bytes, whitespace, key order, or encoding—and webhook signatures are calculated over provider-defined inputs, not the JSON object your application wants to process.
Then verify the endpoint-specific secret, signature header, algorithm, and any timestamp rules for your provider. The details differ between Stripe, GitHub, and Svix, so use that provider’s documentation or SDK rather than borrowing another service’s verification formula.
As an Amazon Associate I earn from qualifying purchases.
1. Preserve the raw body before your framework parses it
At the webhook route boundary, retain the original request body as bytes or as the exact string required by the provider. Verify the signature with that untouched input; parse it into JSON for application logic only after verification succeeds. Re-serializing a parsed object can alter whitespace, key order, or encoding. Stripe says the body must be the exact UTF-8 string it sent, and Svix warns that even slight changes affect verification.
Recommended Free Tools
If verification fails only after adding middleware, inspect whether the framework consumed or transformed the body before your handler receives it. For Express, Stripe’s guide says to register the webhook route before express.json(). For Next.js Pages Router, follow Stripe’s body-parsing guidance and read the request buffer. For AWS API Gateway with Lambda, Stripe documents a mapping template that preserves a rawBody. Use the remedy for your deployed framework and version, not a generic body-parser workaround. Stripe: Manage webhook endpoints
#1 Best Overall
2. Confirm the secret matches this endpoint and delivery path
A valid-looking secret can still be the wrong secret. Stripe’s CLI-forwarded endpoint secret differs from the secret for an endpoint managed in the Dashboard; both use the whsec_ prefix, but they are not interchangeable. Check which endpoint generated the delivery and retrieve the matching secret from that configuration.
For GitHub, confirm that a webhook secret is configured and that your server uses that same secret. GitHub notes that the signature header is absent if no secret is set. Store production secrets securely and keep them out of source code, logs, shell history, and untrusted debugging tools. GitHub Docs: Validating webhook deliveries
3. Match the provider’s header and signing format
Do not assume that webhook providers sign the same fields or use the same header names. A correct HMAC calculation with the wrong inputs is still incorrect verification.
| Provider | Inputs and format to check | Important distinction |
|---|---|---|
| GitHub | Use the configured secret and payload with HMAC-SHA256; compare against X-Hub-Signature-256, whose value uses a sha256= prefix followed by a hex digest. |
X-Hub-Signature is the legacy SHA-1 header. GitHub recommends constant-time comparison and says, “Never use a plain == operator.” |
| Stripe | Use the exact raw UTF-8 body, the Stripe-Signature header, and the secret for the endpoint that received the event. |
Use Stripe’s official SDK verification method; inspect header extraction as well as the three inputs. |
| Svix | Use Webhook-Id, Webhook-Timestamp, Webhook-Signature, and the raw body. Svix signs the message ID, timestamp, and body in its documented format with HMAC-SHA256. |
Its input format and timestamp rules are Svix-specific, not a universal webhook standard. |
For provider-specific details, consult the GitHub validation guide, Stripe endpoint guide, or Svix CLI guide. Stripe’s documented error “No signatures found matching the expected signature for payload” means at least one of the raw body, signature header, or endpoint secret supplied to verification is incorrect.
Rank #3
4. Check whether middleware or an intermediary changed the request
After confirming what reaches the route, check the full request path. Framework middleware may parse or consume the body, while a proxy or load balancer may rewrite the payload or remove headers. Compare the body and relevant signature headers at the point they enter your application with what the provider sent. Do not normalize JSON, change character encoding, or rename headers before verification. GitHub and Stripe both identify intermediaries or framework handling as possible causes.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.5. Check time only when the signing scheme uses timestamps
Some providers include a timestamp in the signed content and reject requests outside an allowed time window. Svix’s libraries reject timestamps more than five minutes in the past or future and require a sufficiently synchronized server clock. That five-minute tolerance is specific to the Svix behavior documented here; it should not be applied to providers whose scheme does not use it. If you use a timestamp-based scheme, check server time synchronization as well as the timestamp header and the provider’s own tolerance rules.
6. Reproduce a request without exposing secrets
Use the provider’s own SDK, documentation, and delivery tools as the default way to inspect verification. Stripe Workbench and Stripe CLI can help examine delivery details and reproduce events; Svix documents svix verify and Svix Play for development inspection. Choose tools that fit the provider and your data-handling requirements. Never paste production secrets or sensitive payloads into an untrusted online debugger, and avoid commands that place secrets in shell history.
Free tools Windows power users keep installed
One-click scans. No signup required.
EventDock’s webhook-sig repository describes local verification for several providers, including Stripe, GitHub, Shopify, Slack, Twilio, and Svix. It is a third-party project; its own repository is evidence of its stated features, not independent validation of its security or maintenance. EventDock webhook-sig repository
7. Separate signature verification from delivery failures
If the signature validates but the event still does not process, move to a separate diagnosis: endpoint reachability, TLS, response codes, timeouts, and application behavior. A provider’s delivery status can show whether the request reached your endpoint and what response it received, but a transport or processing failure is not the same as a signature mismatch. Stripe’s endpoint guide covers delivery troubleshooting as a distinct concern.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




