flashman
← All posts

Base64 and UTF-8 webhook signatures: debug byte mismatches

Fix Base64 and UTF-8 webhook signature bugs by comparing raw bytes, payload encoding, hashes, headers, retries, and carefully redacted production examples.

2026-07-13 · 5 min read · Rahul Chitturi

  • base64
  • webhooks
  • debugging

Webhook signature failures are often byte bugs, not crypto bugs. The provider signs an exact byte stream, but the receiver may parse JSON, normalize Unicode, trim whitespace, or decode Base64 before verifying the header. One invisible transformation makes a correct secret look wrong.

Before rotating secrets, capture the raw body as received by your framework and compare it with the body used by the signature verifier. If those inputs differ, the HMAC or hash function is probably doing exactly what it should.

Preserve the signed payload

Most webhook providers document whether they sign raw bytes, a timestamp plus body string, or a decoded payload. Treat that contract as part of the API. Verification should happen before JSON parsing changes field order or whitespace.

  • Check whether the framework exposes rawBody, text, buffer, or parsed JSON
  • Confirm Base64 fields are decoded only after signature verification when required
  • Normalize neither line endings nor Unicode unless the provider contract says so
  • Compare signature headers from retries with the exact payload stored for each attempt

Use sanitized fixtures

A good reproduction includes a fake secret, a raw payload, the expected signature header, and the verification code path. Keep production customer payloads local, but preserve important bytes such as quotes, slashes, padding, and newline characters in synthetic examples.

When a fix changes middleware order, diff the request handling path before and after. Body parsers, compression, edge functions, and logging middleware can all consume or transform the stream before verification runs.

A Flashman workflow

Use the Base64 tool to inspect encoded fields, the hash generator for local signature experiments, the JSON formatter for parsed payloads, and the diff tool to compare raw and transformed examples.

Never paste live webhook secrets into a browser tab. Use throwaway values for verification math and keep provider signatures tied to sanitized payloads.

Try these tools