flashman
← All posts

Webhook signature mismatch? Debug payloads safely

Debug webhook signature mismatches by preserving raw payloads, checking hashes, comparing headers, and formatting JSON without breaking verification in prod.

2026-06-20 · 5 min read · Rahul Chitturi

  • webhooks
  • api
  • debugging

Stripe, GitHub, Twilio, and internal event buses all use webhook signatures to prove a payload was not changed in transit. When verification fails, teams often start by pretty-printing the JSON. That helps humans read it, but it can also change the exact bytes the signature was calculated over.

Preserve the raw body

Signature verification must use the raw request body from the HTTP framework, not a parsed object serialized back to JSON. Whitespace, key order, trailing newlines, character encoding, and escaped Unicode can all change the digest.

In Node, Rails, Django, and serverless platforms, confirm how to access the raw body before middleware consumes it. Log metadata and hashes, not full production payloads with customer data.

Check the signature inputs

A staging secret against a production webhook URL produces the same symptom as payload mutation. Verify environment first so you do not chase phantom JSON bugs.

  • Header name and algorithm match the provider documentation
  • Secret belongs to the same environment as the webhook endpoint
  • Timestamp tolerance allows normal clock skew but rejects replays
  • String-to-sign order matches the spec, often timestamp plus raw body

Compare without mutating

Use a hash of the raw body as a stable fingerprint when comparing logs, retries, and local test fixtures. If you need to inspect structure, format a copy of the JSON after saving the raw bytes used for verification.

Diff the received headers and body metadata between a passing request and a failing request. Convert provider timestamps to human time when debugging replay windows or clock drift.

A Flashman workflow

Flashman's JSON formatter, SHA hash tool, diff viewer, and timestamp converter all run in your browser. That makes them useful for webhook incidents where payloads are sensitive and you need fast local checks before changing server code.

  • Save a redacted raw payload fixture before parsing
  • Hash the raw fixture to confirm it stays unchanged
  • Format a copied JSON payload for human review
  • Diff passing and failing samples to isolate real drift

Try these tools