48-hour launch: 40% off with code LAUNCH40, Guide $5.40 / Kit $11.40

Stripe webhook failing with 301, 302, 307 or 308 redirect: how to fix

Stripe doesn't follow redirects on webhook deliveries. Its docs say any 3xx response is treated as a failure, and the fix is to set the endpoint to the URL the redirect points to. Your code never runs. Something in front of it sends the redirect.

Common causes

  1. Apex vs www. Your host redirects example.com to www.example.com, or the other way round. Vercel does this with a 307 or 308 when one domain is set to redirect to the other. Register the domain that actually serves the request.
  2. http to https. The endpoint was saved as http://, and your server or CDN upgrades it with a 301 or 308. Use https://.
  3. Trailing slash. Your framework adds or removes the slash. In Next.js, trailingSlash: true sends /api/webhook to /api/webhook/ with a 308. Django's APPEND_SLASH answers a POST to the slash-less URL with a 301 in production, and raises a RuntimeError in DEBUG. Make the registered URL match your route exactly.
  4. Auth middleware. Next.js middleware (Clerk, NextAuth, Supabase helpers and the like) sends unauthenticated requests to a sign-in page, often with a 307. Stripe never has a session, so leave the webhook path out of the middleware.
  5. Locale or rewrite rules. i18n prefixes (/en/...) or host-level redirect rules that also match the webhook path.

Find the redirect in 10 seconds

curl -i -X POST https://your-domain.com/api/webhooks/stripe -d '{}'
# A 3xx with a Location: header means your server redirected.
# A 400 means the request reached your code; the signature check failed, which is expected for this dummy body.

Exclude the webhook from Next.js middleware

// middleware.js
export const config = {
  matcher: ['/((?!api/webhooks|_next/static|_next/image|favicon.ico).*)'],
};

Then put the final URL into the Stripe Dashboard (Developers, Webhooks, your endpoint, Update details) and use Resend on a failed event to confirm it now returns 2xx. Once the redirect is fixed, signature errors are the next most common failure. See Next.js signature errors and No signatures found.

Once the redirect is fixed, signature errors are usually next. The guide covers every common Stripe webhook failure with copy-paste fixes. The kit is a self-hosted Cloudflare Worker relay that verifies Stripe signatures, then retries, replays or dead-letters each event instead of dropping it.

Fix Your Stripe Webhooks guide · Self-Hosted Webhook Relay Kit. Code LAUNCH40 = 40% off until Sun Oct 11, 6:40 AM MT.

Free download: Webhook debugging cheat sheet.

Still failing? Paste your payload, header and secret into the free Stripe signature checker. It runs in your browser and tells you which cause it is.

All five common causes with copy-paste fixes: Fix Your Stripe Webhooks guide ($9). Retries, replay and a dead-letter list in front of your endpoint: the self-hosted relay kit ($19).