Webhook signature mismatch: systematic diagnosis
A signature mismatch means the received signature and locally computed signature differ. Diagnose the signing inputs before rotating secrets or disabling verification.
The signing contract
| Input | Mismatch examples |
|---|---|
| Secret | Wrong environment, endpoint, installation, or incomplete rotation. |
| Message | Parsed JSON, changed whitespace, timestamp prefix, or wrong field order. |
| Algorithm | SHA-1 vs SHA-256 or a provider-specific construction. |
| Encoding | Hex vs Base64, text vs bytes, or missing prefix. |
| Comparison | Different lengths, unsafe normalization, or non-constant-time comparison. |
| Timestamp | Expired delivery or unsynchronized server clock. |
Diagnosis procedure
- Identify the provider contract, signature header, algorithm, encoding, and timestamp rules.
- Confirm the header is present in the request that reached the verifier.
- Capture the exact raw body before any parser, decompression change, or re-serialization.
- Confirm the secret belongs to the same endpoint and environment.
- Recompute the signature using the documented construction and compare safely.
- Inspect the first divergent reconstruction step rather than comparing secret values in logs.
- Send a new provider event after correcting the input.
Do not reconstruct JSON
javascript
// Incorrect: the original byte sequence has already been lost.
const message = JSON.stringify(req.body);
// Correct: retain the raw request bytes before parsing.
const message = req.rawBody;Secret rotation
Coordinate rotation so the sender and receiver overlap only when the provider supports multiple active secrets. Record the rotation time and test a new event. Never print full secrets or expected signatures to application logs.
Verify the fix
- A new delivery passes verification with the intended endpoint secret.
- The verifier uses the raw body and correct encoding.
- Old or tampered requests fail without exposing credential material.