Open inspector →
developer guide

Webhook 401 Unauthorized: How to Fix It

A webhook 401 is the secret, HMAC bytes, Basic auth, or clock skew. Capture the request, then fix that one cause.

A webhook 401 Unauthorized means the endpoint ran an auth check and rejected the sender. It is not a missing route (404) and not an application crash (500). Fix the check that returned 401. Capture the provider’s exact request in a webhook inspector, then replay it with cURL so the input stays constant.

This page is only 401. Status catalogs live in common webhook HTTP errors. Stripe’s HMAC message is signature verification failed.

Secret does not match this URL

Most providers sign with a per-endpoint secret. A 401 often means you verified with:

  • the secret API key instead of the webhook signing secret;
  • a test secret against a live endpoint, or the reverse;
  • a secret from a different endpoint URL;
  • an environment variable that was never loaded in this process.

Confirm the secret in the provider dashboard for this destination URL. Rotate it once if it may have leaked, then update only that handler.

HMAC ran on the wrong bytes

The provider hashed the raw body. If you parsed JSON and hashed a new string, the digest will not match and many stacks map that to 401 or 403.

Use --data-binary when replaying:

curl -i -X POST http://127.0.0.1:3000/webhooks \
  -H 'content-type: application/json' \
  -H 'x-hub-signature-256: sha256=CAPTURED' \
  --data-binary @captured-body.json

Header names differ (Stripe-Signature, X-Hub-Signature-256, X-Shopify-Hmac-Sha256, X-Twilio-Email-Event-Webhook-Signature). Verify the header the provider actually sent, not the one from another vendor’s docs.

Basic auth or generic middleware

A 401 with WWW-Authenticate: Basic is rarely a webhook signature. Some apps protect every route with HTTP Basic, a session cookie, or JWT middleware meant for browsers.

Webhooks are machine-to-machine. Exclude the webhook path from login, CSRF, and Basic. Authenticate with the provider’s HMAC or public key. If you must keep Basic, put the credentials in the provider’s destination URL only when that vendor documents it, and never log the URL.

Clock skew

Several providers reject a signature when t or a timestamp header is outside a tolerance window (often five minutes). A correct HMAC still yields 401.

Check the server clock:

timedatectl status
date -u

Enable NTP. If the handler is in a container, the container clock is the one that matters.

Isolate the layer

  1. Replay the captured request at the public URL. If that 401s, the deployed handler or proxy auth is wrong.
  2. Replay the same bytes at 127.0.0.1. If only localhost succeeds, the secret or middleware differs in production.
  3. Temporarily log whether you entered the verifier and which header was present. Do not log the raw secret or the full payload in production.

A webhook should return 401 only when the sender cannot be authenticated. A well-formed but unwanted event is a business decision, not an auth failure.

Related guides