# X_WEBHOOK_SIGNATURE_INVALID

## Means

the inbound webhook is not signed by the holder of this secret

## Typical cause

four conditions, one code: no readable `x-ultimate-webhook-signature`, an id or topic header outside 1–200 characters or carrying a `:` or a control character, a mac that does not match the bytes that arrived, or a secret the two sides disagree about. The header check is refused **before** the mac is taken — the signed string is `v1:<t>:<id>:<topic>:<body>`, so id `evt:01HZ` with topic `orders.paid` and id `evt` with topic `01HZ:orders.paid` build the SAME bytes, one mac authenticating two differently-labelled deliveries. **401 and never 400**: the request is well formed and carried a CREDENTIAL, so what failed is authentication. Never 403 either, which means an authenticated caller was refused, and there is none here. Does not trigger `signInRedirect`, which keys on `X_UNAUTHENTICATED` alone — a sender is not a browser and has no session to go get. `cause` names only what the framework chose: never the signature, never the secret, never the body

## Fix

sign the delivery with the secret this endpoint was registered under, or re-read the secret from your sender dashboard and pass it as `verifyWebhookSignature(request, { secret })`

[HTTP](/error-codes#http)
