If webhook signature verification started failing after you added JSON or form-parsing middleware, check whether that middleware changed or consumed the request body before verification. A signature must be checked against the exact input the provider signed—not a parsed object or a newly serialized version. Capture the original request bytes for the webhook route, then check the provider’s specific header, algorithm, secret, and timestamp rules.
Why parsing can break webhook signature verification
A webhook signature authenticates a particular request representation. Parsing JSON turns the incoming bytes into data structures; serializing those structures again can produce different bytes even when the resulting JSON means the same thing. Whitespace, key order, escaping, and character encoding can all affect the signed input.
Middleware can also consume the request stream before the webhook handler sees it. The verifier may then receive an empty body, a parsed object, or a reconstructed string rather than the original bytes. Stripe says verification requires the raw, unmodified body; Slack likewise instructs developers to read the raw body before deserialization, and Twilio SendGrid’s Node.js guide calls for verifying a raw Buffer or string.
Debug the failure in this order
- Identify the provider and exact error. A digest mismatch is different from a timestamp-freshness failure. Stripe’s “no signatures found matching the expected signature for payload” troubleshooting points to a modified body or an incorrect endpoint signing secret. See Stripe’s webhook troubleshooting guidance.
- Find the first middleware that reads the body. Trace the order of global JSON, URL-encoded/form, multipart, framework-adapter, and custom parsing middleware relative to the webhook route. A parsed object—or JSON made by serializing that object again—is not the raw request body.
- Preserve the original bytes for the webhook route. Configure the route or framework to make the provider’s expected raw representation available to the verifier before deserialization. In its Node.js example, SendGrid excludes the webhook route from JSON parsing and applies raw parsing on that route. The exact configuration depends on the framework and hosting adapter. See the SendGrid Event Webhook guide.
- Compare the body at key boundaries. During debugging, compare byte length and a temporary digest at the earliest application boundary and immediately before verification. Avoid logging signing secrets or full sensitive payloads. Check whether a proxy, load balancer, serverless adapter, decompression layer, or text-decoding step changed the body or signature headers. GitHub specifically warns that proxies and load balancers must not modify payloads or headers; its guidance also addresses UTF-8 handling.
- Check the provider’s signature inputs and secret. Confirm that the code reads the provider’s designated header, uses the documented algorithm, and has the correct secret for the receiving endpoint and environment. For example, Stripe’s endpoint signing secret must match the endpoint delivering the event; its CLI listener uses a distinct secret. GitHub recommends its SHA-256 header and the configured webhook secret.
- Investigate timestamps only when the failure indicates a freshness problem. Check timestamp construction and server clock accuracy according to that provider’s scheme. Slack’s signed base string includes a timestamp and its guide demonstrates a five-minute freshness check; that is Slack-specific, not a universal tolerance. Stripe advises checking server time and verifying promptly when its library reports a timestamp outside tolerance.
- Verify before processing event data. Keep authentication ahead of business logic, and use a constant-time comparison method where implementing verification yourself. GitHub and Slack both recommend constant-time comparison rather than ordinary direct equality.
Provider-specific details that should not be mixed
| Provider | Signature inputs and header | Secret and additional checks |
|---|---|---|
| Stripe | Raw, unmodified incoming request body; use the provider’s signature-verification mechanism and expected signature header. | Use the signing secret for the receiving endpoint and environment. A Stripe CLI listener secret is different. For timestamp-tolerance failures, check server clock accuracy and verify promptly. Stripe troubleshooting. |
| GitHub | Prefer X-Hub-Signature-256 with HMAC-SHA256. GitHub describes the signature as a sha256=-prefixed HMAC hex digest based on the secret and payload. |
Use the configured webhook secret, keep payload and headers unchanged, and handle UTF-8 as required by the server. Validate before processing and compare in constant time. Troubleshooting · Validation. |
| Slack | Use X-Slack-Signature and HMAC-SHA256. Slack builds a versioned signed base string from the version, timestamp, and raw body; read the body before JSON or other deserialization. |
Check timestamp freshness using Slack’s procedure; its guide demonstrates rejecting timestamps more than five minutes from local time. Use a constant-time comparison. Slack request verification. |
| Twilio SendGrid Node.js | Verify the raw body as a Buffer or string. | If using express.json() or bodyParser.json(), exclude the webhook route from that parser and apply raw parsing on the route, following the guide’s example. SendGrid Event Webhook guide. |
Keep delivery timing separate from signature debugging
Changing body parsing addresses what the verifier receives; it does not by itself resolve delivery timeouts. GitHub says a webhook delivery should receive a 2xx response within 10 seconds or GitHub treats the delivery as failed. Treat that as delivery-response timing guidance, not as an explanation for a signature mismatch. See GitHub’s troubleshooting guide.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteQuick Recap
Rank #4
Rank #2
#1 Best Overall
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.

