Webhook Not Received? A Systematic Debugging Checklist
A step-by-step checklist for when a webhook never arrives: confirm the provider sent it, rule out URL/DNS/firewall issues, check event subscriptions, and isolate where it was lost.
Ozer
Developer & Founder of HookSense
A webhook that never arrives is uniquely frustrating: there's no error to read, just silence. The key to debugging it fast is to stop guessing and instead isolate where the request was lost — at the provider, in the network, or at your application. This checklist does exactly that, in order.
Step 1: Did the provider actually send it?
Always start here. Every major provider keeps a delivery log, and it answers the most important question for free:
- Stripe: Developers → Webhooks → click the endpoint → the event → delivery attempts.
- GitHub: repo or org Settings → Webhooks → the webhook → Recent Deliveries (shows request and your response).
- Shopify: webhook delivery is visible via the API and partner tooling; failed deliveries are retried for up to 48 hours.
If the provider shows no delivery at all, your server was never the problem — skip ahead to Step 2. If it shows a delivery with a non-2xx response or a timeout, the request reached you and the issue is in your app — jump to Step 5.
Step 2: Are you subscribed to the right event, on the right object?
The classic "not firing" cause is that the event you're waiting for isn't one you subscribed to. If you selected only push on a GitHub webhook, you'll never see pull_request. If you registered checkout.session.completed on Stripe, you won't get payment_intent.succeeded.
Also confirm scope: GitHub webhooks can live on a repository or an organization; Stripe events can be account-level or Connect-account-level. A webhook configured at the wrong scope silently never fires for the events you expect.
Step 3: Is your endpoint reachable from the public internet?
If the provider claims it sent the event but your server has no record, something between the internet and your app dropped it. Isolate it with an external inspector:
- Point the provider (or a plain
curlfrom outside your network) at a public HookSense URL. - If the request lands on the inspector but not your server, the loss is in your edge: DNS, a dead tunnel, a firewall, a WAF, or an IP allowlist.
- If it doesn't even land on the inspector, the provider isn't really sending — go back to Steps 1 and 2.
This single test cleanly splits "provider problem" from "my-network problem," which is usually where the hours disappear.
Step 4: Rule out the network layer
When requests reach an external inspector but not your origin, check, in rough order of likelihood:
- Tunnel died: ngrok and similar tools hand out a new URL on every restart — the provider is still pointed at the old one. A permanent endpoint avoids this entirely.
- Firewall / security group: inbound POST to your port is blocked. Many providers publish webhook IP ranges to allowlist.
- WAF or CDN: some block unfamiliar POST traffic or specific user agents. Check the WAF's blocked-request log.
- Wrong path or trailing slash:
/webhooksvs/webhooks/can 404 depending on your router. - HTTPS / certificate: most providers refuse to deliver to an endpoint with an invalid TLS certificate.
Step 5: Confirm your handler accepts it
If deliveries arrive but the provider logs a non-2xx, your handler is the issue — a crash, a slow response that times out (Stripe expects a response within 20 seconds), or a redirect the provider won't follow. Capture the failing request, replay it locally with a debugger attached, and watch exactly what your handler does.
The fastest path
The reason a public inspector saves so much time is that it removes ambiguity: you see, with certainty, whether the request reached the internet-facing edge at all. HookSense gives you a permanent URL in one second, streams requests in real time, and lets you replay any captured request to localhost — so you can reproduce the "missing" webhook on demand. Create a free endpoint and use it as your ground truth.
Related posts
Try HookSense Free
Inspect, debug, and replay webhooks in real-time. No credit card required.
Get Started Free