Skip to content

HMAC signature verification failing

Your receiver is rejecting webhook deliveries because X-Webhook-Signature does not match what your code computes, or you are seeing 401/403 responses in the delivery log that you did not expect.

Signature verification fails for one of three common reasons:

  1. Wrong signing secret — you are computing the HMAC with the wrong key (for example, the secret from a different endpoint, an old secret before a recreate, or a secret that was not stored correctly).
  2. Body serialization mismatch — you are computing the HMAC over a parsed or re-serialized body rather than the raw request bytes. The signature must be computed over the exact bytes MapleGather sent.
  3. Timestamp tolerance exceeded — your receiver is checking that X-Webhook-Timestamp is within five minutes of the current time, and the delivery was dispatched more than five minutes ago. This is correct behavior — reject old deliveries.

Step 1 — Verify you are using the right secret.

Go to Admin & Security > Integrations > Webhooks and confirm which endpoint corresponds to your receiver URL. The signing secret for this endpoint was shown once when you created it. If you are unsure which secret you stored, rotate the signing secret in place (see Step 5 below) — no need to delete the endpoint.

Step 2 — Check your signed-string construction.

The correct signed string is:

<X-Webhook-Timestamp>.<raw request body>

Common mistakes:

  • Using body = json.dumps(request.json()) re-serializes the body (may differ in whitespace, key order). Use the raw bytes from the incoming request stream before any parsing.
  • Omitting the period separator between timestamp and body.
  • Adding extra whitespace or encoding the timestamp differently.

Step 3 — Check your timestamp window.

If your receiver rejects deliveries due to the five-minute window, confirm your server clock is synchronized with NTP. A clock drift of more than five minutes causes all deliveries to be rejected.

Note: replayed deliveries (from the Replay action in the delivery log) regenerate the signature at the current timestamp. Your five-minute window should accept them.

Step 4 — Send a test event.

To send a test event: go to Admin & Security > Integrations > Webhooks, find your endpoint, and select Send a test event on the endpoint screen (or re-run the New endpoint flow on a test endpoint pointed at a request-inspection service such as https://webhook.site to see the exact headers MapleGather sends).

To inspect the resulting ping delivery: select ⋮ > View deliveries on the endpoint to open the delivery log and check the outcome. See Create a webhook endpoint step 7 for the canonical test-send path.

Step 5 — If the secret is lost.

If you have lost the signing secret and cannot reconstruct it, rotate it in place: go to the endpoint detail, select ⋮ > Rotate secret (webhook_secrets_rotate). This issues a new whsec_… secret without recreating the endpoint — the endpoint id, URL, and event subscriptions are preserved. Copy and store the new secret carefully before dismissing the reveal.

If you have verified the secret, the signed string, and the clock, and signatures are still not matching, contact support with:

  • Your endpoint URL (not the signing secret).
  • A sample X-Webhook-Signature value and the raw body you used to compute your expected digest.
  • Your code for constructing the signed string.