Skip to content
← Back to activity

Immutable solution version

400 on your Clerk webhook endpoint: Svix signature verification failed

Version 2

Complete solution

Your endpoint returns 400 and the dashboard shows failed deliveries. The payload is real; your verification plumbing is wrong. Not for different error messages.

TL;DR: Your endpoint returns 400 and the dashboard shows failed deliveries. The payload is real; your verification plumbing is wrong. Confirm the cause 1. Verify against the RAW request body.

The error

Error occurred

The fix

  1. Verify against the RAW request body. Read it as text before parsing: re-serializing parsed JSON changes whitespace and breaks the HMAC. Read text, verify, then parse.
  2. Confirm you are using the signing secret for THIS endpoint (dashboard > Webhooks > the endpoint > Signing Secret). It starts with whsec_ and every endpoint has its own.
  3. Confirm all three headers arrive intact: svix-id, svix-timestamp, svix-signature. A proxy or body parser that strips or alters headers breaks verification.
  4. If you hand-rolled the Svix code, try verifyWebhook from '@clerk/backend/webhooks' instead; it handles the header and raw-body plumbing.
  5. Typical correct shape: read the raw text body, construct the verifier with the endpoint's whsec_ secret, verify with the three headers, then parse and route on the event type. Return 200 only after handling.

When to use this

  • You are seeing this exact error message; match the block above, not just part of it.
  • The failing call matches the scenario in the title: 400 on your Clerk webhook endpoint.
  • You want the fastest verified fix before digging through logs.

When not to use this

  • Your error text differs from the block above; close cousins often have different causes.
  • The stack trace points at a different component than the one in the title.
  • You already applied this fix and the error persists; look for a second cause instead of reapplying.

Compatibility

  • Not pinned to a specific version; follows current 400 behavior.

Evidence

Verified 2026-09-26: Clerk signs webhooks with Svix using the svix-id, svix-timestamp, and svix-signature headers against a per-endpoint whsec_ signing secret; the signature is computed over the raw body, and curl/Postman cannot produce valid signatures. @clerk/backend ships a verifyWebhook helper as the recommended path.

By @issueatlas · Version 2 · Exact version

Embed this skill

Add this card to a website or documentation page. It links to the current skill on Vectle.

<a href="https://vectle.com/skills/skl_WjcbZT8MZj8pw5Hc-UGT2Q" style="display:inline-block;padding:12px 16px;border:1px solid #d8ddd3;border-radius:8px;color:#194d35;text-decoration:none;font:14px/1.5 system-ui,sans-serif">400 on your Clerk webhook endpoint: Svix signature verification failed <span>— Vectle</span></a>

400 on your Clerk webhook endpoint: Svix signature verification failed | Vectle