Webhook Debugging Guide
Webhook failures are frustrating because the failing request is sent by another system. GitHub's webhook documentation recommends validating deliveries with a secret and signature before processing the payload, and its validation guide documents the X-Hub-Signature-256 HMAC-SHA256 flow at GitHub Docs. This Formalint page keeps the same operational discipline for any webhook provider.
Webhook delivery checklist
| Layer | Check | Why it matters |
|---|---|---|
| Provider | Delivery ID, event type, retry count and response status. | Confirms whether the sender reached your endpoint. |
| Network | DNS, TLS, firewall, reverse proxy and timeout behavior. | Many webhook systems require a public HTTPS URL. |
| App | Raw body, signature verification, JSON parsing and route matching. | Changing the body before verification can break signatures. |
| Processing | Idempotency, queue handoff and duplicate detection. | Retries can deliver the same event more than once. |
| Response | Return a fast 2xx after accepting the event. | Slow business work should move to a queue when possible. |
Replay a saved payload locally
curl -i -X POST http://127.0.0.1:3000/webhooks/provider \
-H "Content-Type: application/json" \
-H "X-Webhook-Event: sample.created" \
-H "X-Delivery-Id: local-replay-001" \
--data @payload.jsonSignature debugging
- Verify against the raw request body, not a re-stringified JSON object.
- Use the provider's exact header name and algorithm.
- Store webhook secrets outside the repository and deployment image.
- Use constant-time comparison when comparing signatures.
- Log whether verification passed, but do not log the secret.
Idempotency pattern
delivery_id = request.headers["x-delivery-id"]
if delivery_id already processed:
return 200
verify signature
store delivery_id as received
enqueue business work
return 202Incident note template
provider:
event type:
delivery id:
delivery timestamp:
provider response status:
endpoint URL:
signature header present:
raw body preserved:
duplicate event:
queue accepted:
handler error:
retry behavior:Webhook handlers should be boring: verify, record, enqueue and respond. Expensive work inside the request path makes retries and timeouts harder to reason about.
Related: curl API Debugging Cheatsheet, JSON Diff, API Debugging Checklist, Nginx Reverse Proxy Checklist.