Stripe webhook · server log

Timestamp outside the tolerance zone

what it looks like
StripeSignatureVerificationError: Timestamp outside the tolerance zone

What it means

The stripe-signature header carries a timestamp, and the library rejects events older than the tolerance (300 seconds by default) to stop replay attacks. Either your server clock is off, or you're replaying an old saved payload.

Common causes

  • Server or container clock drift (no NTP)
  • Replaying a saved request from a fixture or log
  • Queueing the raw request and verifying it minutes later

How to fix it

  1. Sync the server clock (NTP) and check date -u against real UTC
  2. Verify the signature as soon as the request arrives, then queue the parsed event
  3. For tests, generate fresh headers with stripe.webhooks.generateTestHeaderString instead of old ones
verify the fix
date -u   # should match real UTC
stripe listen --forward-to localhost:3000/api/stripe/webhook
# put the whsec_... it prints in .env.local, then restart npm run dev
stripe trigger checkout.session.completed

pass if Fresh events verify and return [200]. Don't raise the tolerance to make old payloads pass.

works with stripe-node 23.0.0 · Next.js 16.4.3 App Routerlast verified CLI steps: Stripe CLI 1.55.2, Oct 27, 2026

Prompt for Cursor or Claude Code

My Stripe webhook fails with 'Timestamp outside the tolerance zone'. Check whether verification happens immediately on receipt or later from a queue, and whether tests replay stale signed payloads. Make verification run on receipt and use stripe.webhooks.generateTestHeaderString in tests. Don't raise the tolerance.

Not quite your error? Paste yours into the free VibeBoot Doctor or browse the Stripe webhook fixer.

next: skip the next one

Skip the debugging. The VibeBoot SaaS Starter ships with this already handled: a signature-verified webhook (raw body + constructEvent) that re-fetches the subscription from Stripe before saving it, with Vitest tests. Plus auth and a database on Next.js 16.4.3. $49, one-time.

14-day money-back guarantee · lifetime updates

$ fixed it? get the next one first

New fixes for what AI agents break, by email.

When we add a fix or a Cursor rule for a new Next.js, Auth.js, Prisma or Stripe break, it goes out in the VibeBoot newsletter. Free, occasional, unsubscribe in one click.

Subscribe free