Short answer
Open the endpoint’s Event deliveries tab and read the status: a redirect, a 4xx, a 5xx, a TLS error or a timeout. Fix that, return 200 before slow work, then list events with delivery_success set to false and process what you missed.
Rather not fix it yourself? Stripe Billing Fix and Setup handles it at a fixed price, agreed before work starts.
Why Stripe can’t deliver the event, and the fix
01
The URL redirects
“We consider redirect responses to webhook requests as failures.” Stripe, Debug webhook deliveries
http to https, the bare domain to www, or a missing trailing slash all send a redirect. Save the exact final URL as the endpoint.
02
Your app blocks the request
“you might need to exempt the webhooks route from CSRF protection.” Stripe, Webhooks (CSRF)
A 401 or 403 usually means login middleware, deployment protection on a preview URL, or CSRF checks. A 405 means the route doesn’t accept POST, and a 404 means the path is wrong. Make the endpoint public and let POST through.
03
The handler times out
“Make sure you defer complex logic and return a successful response immediately in your webhook handling code.” Stripe, Debug webhook deliveries (timed out)
Sending emails or updating several systems before you respond can run past the time limit. Save the event, return 200, then do the work. On serverless hosts, work after the response may be cut off, so run it from a queue or a scheduled job.
app.post('/webhooks/stripe', express.raw({ type: 'application/json' }), async (req, res) => { let event; try { event = stripe.webhooks.constructEvent(req.body, req.headers['stripe-signature'], process.env.STRIPE_WEBHOOK_SECRET); } catch (err) { return res.sendStatus(400); } await saveEvent(event); res.sendStatus(200); processEvent(event.id).catch(console.error); });04
Events were missed while it was down
“Set to false to return only events that failed delivery to at least one of your endpoints.” Stripe, Process undelivered events
After the fix, list the failed events and run them through your handler, skipping any event ID you already processed. Stripe returns only events from the last 30 days, and 10 per page by default, so page through the rest.
const failed = await stripe.events.list({ delivery_success: false, limit: 100 });
Checked against the vendor’s docs on : Stripe docs: Manage webhook endpoints; Stripe docs: Webhooks.
Rather hand it over?
Fixed scope, fixed price, paid upfront. The work happens in writing; no call needed.
- $950Stripe Billing Fix and SetupSubscriptions, webhooks, customer portal and failed payments set up or fixed, tested in Stripe test mode.See scope and start
- from $450App Fix TicketOne reproducible bug in an existing mobile or web app, diagnosed and fixed.See scope and start
- from $450AI-Built App RescueA Lovable, Bolt or Cursor app checked end to end in 3 days, then its worst problems fixed at a fixed price.No issues worth fixing, no charge. If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way. This applies to the first 10 Launch Checks bought after October 30, 2026.See scope and start
“Working with Simon makes everything run so smoothly and better than I could ask for it. Amazingly communicative, extremely knowledgeable of coding and the backend processes. I strongly recommend.”
Related: Stripe webhook signature verification failed · Stripe webhook 200, database not updated · Stripe paid, account not upgraded · Stripe card_not_supported