hooksentinel
Errors

Errors

Index of every error code @hooksentinel/core can throw — HTTP status, retryability, cause, and fix.

Every failure in the verify → deduplicate → parse → handle pipeline produces a HookSentinelError with a stable code, and createWebhookHandler maps that code to an HTTP response automatically unless you override it with onError. This page indexes all eleven codes; each links to a full page with the cause and the concrete fix.

CodeStatusRetryableMeaning
invalid_signature401NoSignature present but doesn't match the computed one
missing_signature_header400NoExpected signature header wasn't sent
malformed_signature_header400NoSignature header present but not in the expected format
timestamp_out_of_tolerance400NoRequest timestamp outside the allowed window
missing_raw_body500NoBody was already parsed before hooksentinel could read raw bytes
payload_too_large413NoBody exceeds the configured size limit
parse_error400NoBody isn't valid JSON, or doesn't match the provider's shape
duplicate_event200NoEvent ID already marked processed — not a failure
idempotency_store_error500YesThe idempotency store was unreachable or errored
handler_error500YesYour onEvent callback threw
provider_verification_error400NoA provider-specific check beyond signature/timestamp failed

How to handle these in code

By default, hooksentinel writes the response for you — you don't need a try/catch around anything. If you want custom logging or a different response shape, use onError:

import { createWebhookHandler, stripe } from '@hooksentinel/core';
import type { HookSentinelError } from '@hooksentinel/core';

const handler = createWebhookHandler({
  provider: stripe({ secret: process.env.STRIPE_WEBHOOK_SECRET! }),
  onEvent: async (event) => { /* ... */ },
  onError: async (error: HookSentinelError, ctx) => {
    if (error.code === 'idempotency_store_error') {
      logger.error('idempotency store down', { provider: ctx.provider, eventId: ctx.eventId });
    }
    // return undefined to fall back to hooksentinel's default response for this code
  },
});

"Retryable" means the provider should redeliver

The retryable column reflects what hooksentinel tells the provider by way of the HTTP status — a 5xx tells Stripe, GitHub, etc. to retry the delivery later; a 4xx tells them not to bother, because retrying the exact same request will fail the same way. Two codes (idempotency_store_error, handler_error) are retryable because the failure is transient or on your side, not a property of the request itself.

Last updated on

On this page