Webhook Error Reference
Debugging a broken webhook at 2am? This reference covers every common webhook error — what causes it, how to fix it, and how to reproduce it with WebhookWhisper to verify your fix.
Bad Request
highYour endpoint rejected a malformed body — parse error, missing required field, content-type mismatch. Most providers do not retry 400s, so the event is dropped.
Unauthorized
criticalSignature verification failed. The computed HMAC does not match the header value — usually caused by using parsed JSON instead of the raw request body.
Forbidden
highA WAF, IP allowlist, or auth gate blocked the request before your handler ran. Common with Cloudflare bot protection or strict origin rules.
Endpoint Not Found
highThe webhook URL returned a 404. Either the URL path is wrong, the route is not registered, or the server is returning 404 for unrecognized paths.
Method Not Allowed
mediumRoute exists but is registered for the wrong HTTP method. Webhooks are POST — a 405 means your handler is configured for GET, PUT, or missing OPTIONS preflight.
Payload Too Large
highBody exceeded a size cap somewhere in your stack — framework parser, reverse proxy, or platform limit. Big Shopify orders and GitHub push events routinely hit this.
Unprocessable Entity
mediumBody parsed but failed schema validation. Usually a strict validator rejecting an evolved provider payload, or an event type your handler did not anticipate.
Too Many Requests
mediumA rate limiter rejected the delivery. Often self-inflicted — too-tight per-IP limits applied to provider egress IPs, or retry storms after recovery.
Internal Server Error
criticalUnhandled exception in your handler. Provider retries on schedule, duplicate deliveries pile up. The structural fix is to ack fast and process async.
Bad Gateway
highReverse proxy could not reach your handler. Container restart, OOM kill, or app crash. Usually deploy-window blip; sometimes signal of operational fragility.
Service Unavailable
highService intentionally refused — maintenance mode, dependency unavailable, circuit breaker open. Always include Retry-After header so retries pace correctly.
Gateway Timeout
highReverse proxy gave up waiting for your handler. Either the handler is too slow or the proxy timeout is too short. Webhook handlers should respond in under 100ms.
Signature Mismatch (Generic)
criticalGeneric HMAC verification failure. Wrong secret, parsing body before verifying, or charset mismatch. See provider-specific pages for tailored fixes.
Stripe Signature Mismatch
criticalstripe.webhooks.constructEvent throws SignatureVerificationError. Usually express.json() before express.raw(), wrong secret, or 5-minute timestamp tolerance exceeded.
GitHub Signature Mismatch
criticalX-Hub-Signature-256 verification failed. Common causes: SHA1 vs SHA256 confusion, missing sha256= prefix, body parsed before HMAC.
Shopify HMAC Validation Failed
criticalX-Shopify-Hmac-Sha256 mismatch. Shopify uses base64 (not hex like Stripe/GitHub) — copy-pasted Stripe verification fails 100% on Shopify.
Twilio Signature Validation Failed
criticalX-Twilio-Signature mismatch. Twilio signs URL+form-params (not raw body) — most failures are URL reconstruction issues behind reverse proxies.
Slack Signature Mismatch
criticalX-Slack-Signature mismatch. Common causes: using bot token instead of signing secret, missing v0 prefix in signed string, or body parsed before HMAC.
SSL Certificate Error
criticalYour webhook endpoint's TLS certificate is invalid, expired, or self-signed. All major providers require a valid HTTPS certificate to deliver webhooks.
DNS Resolution Failed
criticalSource could not resolve your webhook hostname. Domain expired, DNS not propagated, missing AAAA record on IPv6-only network, or DNSSEC misconfiguration.
Connection Refused
highTCP RST from your server — application down, listening on wrong interface, firewall blocked, or port mismatch. Different from 502: no proxy is involved.
Connection Reset
highConnection established and then severed mid-request. Mid-request crash, OOM kill, idle-timeout mismatch, or reverse-proxy buffer overflow.
Webhook Timeout
highYour endpoint did not respond within the provider's timeout window (usually 3–30 seconds). The provider will retry. Respond immediately and process asynchronously.
Raw Body Required
criticalVerification SDK errors saying it needs raw bytes. The body was parsed by middleware before your verification code ran. Use express.raw() on the webhook route.
Duplicate Event Received
mediumSame event arriving multiple times — expected under at-least-once semantics. Implement idempotency keyed on the provider event ID; duplicates should be 200 no-ops.
Event Not Firing
mediumExpected events are not arriving. Common causes: event type not in subscription, endpoint auto-disabled, scope mismatch, or wrong test/live environment.
The 3 Most Common Webhook Mistakes
Parsing the body before verifying the signature
HMAC signature verification requires the raw request bytes — exactly as sent. Using express.json() or body parsers before verification changes the byte sequence and breaks the HMAC. Always use express.raw({ type: 'application/json' }) for webhook endpoints.
Not responding quickly enough
Most providers timeout after 3–30 seconds. If your handler processes synchronously (database writes, API calls, emails), you will hit timeouts and get duplicate deliveries. Return HTTP 200 immediately and process the event in a background queue.
Not implementing idempotency
Providers retry on failure. If your endpoint returns 500 or times out, the same event arrives again. Without idempotency checks on the event ID, this creates duplicate orders, charges, or emails. Always deduplicate using the provider's event ID.
Debug Webhook Errors in Real Time
WebhookWhisper captures every request with full headers, body, and timing — so you can see exactly what the provider sent and reproduce the error.
Start Debugging Free