Error catalogue reference
Every error Notifizz returns has a stable string code so you can match on it programmatically. This page lists the public catalogue: backend HTTP errors, enricher SDK errors, and the HTTP status each maps to.TL;DR
- Backend errors return
{ code: <stable-string>, ... }in the body — except the identity calls (identify,detach,setMeasurementConsent), which name it in{ error: <stable-string>, message }. - Enricher errors (Node SDK) are typed exception classes —
EnricherInputValidationError,EnricherHmacVerificationError, etc. - HTTP status follows the family (
401for auth,400for input,404for not-found,500for handler failure).
Backend HTTP errors
Authorization (auth/*, authorization/*)
Identity calls (identify, detach, setMeasurementConsent)
The identity calls authenticate with your environment’s SDK secret key, which the backend SDKs send for you. The environment of the key is the environment the call acts in.
HTTP / functional (other/*, notification/*)
Admin / event (event/*, region/*, organization-settings/*)
Enricher SDK errors (Node)
The Node SDK (@notifizz/nodejs) ships typed exception classes for the enricher subsystem. client.dispatch(body) encodes them in the response body ({ ok: false, error: { code, message } }) and Notifizz translates error.code back to typed domain errors. The SDK does NOT throw across the dispatch boundary — Promise<DispatchResponse> is the contract. The classes below are the registration-time and internal exceptions you may still want to catch in unit tests.
The error classes themselves are exported from
@notifizz/nodejs so you can instanceof-check them in your own logging or error reporting.
Connector webhook errors
Connector webhooks return HTTP-level errors when signature verification fails — there’s no per-provider error code, just the status. See connector webhooks reference for the per-provider details.SDK retry behaviour
All three event-tracking SDKs retry transient failures twice (1s, then 2s) before bubbling. Errors that bubble:
- Node — original
axioserror after 3 attempts. - Java —
IOException(the last one) after 3 attempts. - PHP — original
GuzzleHttp\Exception\GuzzleExceptionafter 3 attempts.
4xx, e.g. 403 auth/invalid-authorization) are not retried: the call fails at once, since repeating it would give the same answer.
FAQ
input-validation-failed from my enricher — what does the body look like?
input-validation-failed from my enricher — what does the body look like?
The 400 response carries
{ error: { code: "input-validation-failed", message, details } }. The details field is an array of validation issues — for Zod-derived schemas, it’s the Zod issues array; for raw JSON Schemas, it’s Ajv’s errors array. Read the first entry to see which property failed.enricher-not-found but it is registered — why?
enricher-not-found but it is registered — why?
The registry is per-client-instance. If you have two
NotifizzClient instances and only register the enricher on one, dispatch on the other returns { ok: false, error: { code: "enricher-not-found" } }. Make sure the same instance that called enricher() is the one whose dispatch() is wired in the controller.Difference between 400 (event/invalid-name) and 422?
Difference between 400 (event/invalid-name) and 422?
400 covers both grammar violations (event name) and DTO validation (malformed bodies). 422 is reserved for the identity calls, which refuse a request that is well-formed but cannot be honoured: a Subject type they don’t handle (unsupported_subject_type), an empty identifier (invalid_subject_identifier), a disposable email domain in production (disposable_email_domain), two email addresses linked to each other (identify_requires_a_client_id — link each to its user id), or a measurement consent that is not a boolean (invalid_consented). Status follows the family — read the error field of the body to disambiguate. The identity calls also answer 409, for two different reasons: identity_conflict is final (the address is already held by another of your users — the user id you declared is recorded without it), identity_concurrent_update is not (another call changed the same identities at the same moment — nothing was linked, repeat the call).What does other/unknown actually mean?
What does other/unknown actually mean?
A backend exception that didn’t get caught by a more specific handler. Treat it as “infrastructure issue, retry, escalate if persistent”. The
message field has the specific error message; the correlation id (in response headers) lets us trace it.My EnricherHmacVerificationError keeps firing despite correct setup.
My EnricherHmacVerificationError keeps firing despite correct setup.
Read the
reason field. missing-header means the HMAC headers weren’t sent (the backend usually sends them — if missing, the request didn’t come from Notifizz). bad-signature means the secret mismatches or the body was modified (often a JSON parse + re-serialise breaking the byte-for-byte match). stale-timestamp means clock drift outside ±5 minutes — NTP your enricher host.See also
Event Tracking
Detailed error shapes for
POST /v1/events/track.Enrichers protocol
HMAC verification, input/output schemas.
Connector webhooks
Per-provider signature error semantics.
Troubleshooting
Cross-cutting failure modes — symptom → cause → fix.