Every failure iqxWEB or WebHub can produce carries a stable code and a 10‑character reference. The user sees them in the toast as CODE · ref XXXXXXXXXX and reads them out to us. The code says what kind of failure it was; the ref finds the exact request in the logs and in Sentry.
How to look one up
request_id:<ref> (or code:<code> to see how often it happens on that site). The log line for the ref carries a detail field that names the precise cause (e.g. user-not-found, state expired, hub 404 …) — it is never shown to the user for 4xx.docker logs / the Windows service log). Both WebHub nodes and the web server share the ref, so search all of them.
Codes are defined in the npm package @iqx-limited/web-errors (repo IQXLimited/web-errors). Only the status and public message live there; this page is the internal meaning. Do not put internal notes in the package — it is bundled into every browser.
Codes marked user fault log at info/warn and never become Sentry issues — they are not bugs. Everything 5xx becomes a Sentry issue tagged with the code and ref. HUB-* codes mean the IQX Hub / SQL side answered badly; AUTH-SSO-004, AUTH-SSO-010, AUTH-AUTH0-001/002/004, HUB-002, SYS-503 point at our configuration or infrastructure and should be treated as incidents, not user problems.
| Code | Status | Public message | Meaning / what to check |
|---|---|---|---|
| AUTH-PWD-001 | 401 | Invalid username or password. | User fault. The log detail says which: user-not-found, hash-mismatch, or legacy-hub-rejected (a classic Hub said no). Deliberately one message for all three. Repeated user-not-found from one IP = someone guessing usernames. |
| AUTH-PWD-002 | 429 | Too many failed sign-in attempts. | Rate limiter tripped for this user/IP. Check for a stuck client retrying, or an attack. |
| AUTH-PWD-003 | 400 | Please enter your username and password. | Body missing fields. Only a broken client or a hand-made request produces this. |
| AUTH-PWD-004 | 503 | The sign-in service is temporarily unavailable. | Not a bad password: the DB / Hub call behind sign-in failed. Check SQL Anywhere, the Hub, and the pool page under Diagnostics. |
| AUTH-PWD-005 | 400 | The new password does not meet the requirements. | Change/reset password rejected by policy. |
| AUTH-PWD-006 | 400 | This password reset link is not valid or has expired. | Reset token failed verification; detail names the stage (JWTExpired, signature, audience…). A signature failure right after a WebHub restart means the registration key was regenerated — every outstanding link died (a warn line says so). |
| AUTH-PWD-007 | 502 | We could not send the password reset email. | The email send failed. Check the mail configuration on the Hub. |
| Code | Status | Public message | Meaning / what to check |
|---|---|---|---|
| AUTH-USER-001 | 404 | Your account could not be found. | Identity was verified (SSO / magic link) but NetV2RequestUser returned nothing: no IQX person is linked to that login/email, or it is archived. |
| AUTH-USER-002 | 403 | Your account does not have permission to sign in. | The person exists but has no LOGIN right. |
| AUTH-USER-003 | 400 | More than one account matches these details. | Two people share the email/login the provider gave us. Fix the data in IQX. |
| Code | Status | Public message | Meaning / what to check |
|---|---|---|---|
| AUTH-REG-001 | 400 | Please check the registration details and try again. | Validation failed; detail names the field. |
| AUTH-REG-002 | 403 | Self-registration is not enabled on this system. | Web setting is off. Expected if the site does not allow registration. |
| AUTH-REG-003 | 409 | That user name is already registered. | IQXNetUser row exists. Known trap: registration inserts that row before NetV2CandidateRegister and does not roll back, so a failed proc (REG-005/006) makes the next attempt show this. Delete the orphan row. |
| AUTH-REG-004 | 409 | That email address is already registered. | As above, by email. |
| AUTH-REG-005 | 400 | Registration could not be completed with the details provided. | The register proc returned an IQXFailure (business validation). The proc's message is in detail. |
| AUTH-REG-006 | 500 | Registration could not be completed. | The proc or DB threw. Sentry issue. |
| AUTH-REG-007 | 400 | This registration link is not valid or has expired. | Registration token failed verification (detail names the stage). Same key-regeneration caveat as PWD-006. |
| AUTH-REG-008 | 500 | Registration is not available right now. | Registration signing key missing/unusable. Configuration problem on WebHub. |
| Code | Status | Public message | Meaning / what to check |
|---|---|---|---|
| AUTH-SESSION-001 | 401 | You are not signed in. | No bearer token and no accessToken cookie. Normal after logout; from an app it means the cookie was lost. |
| AUTH-SESSION-002 | 401 | Your session is no longer valid. | Token signature/issuer/audience invalid, or it is an API/registration token used on a user route. After a WebHub key rotation every session shows this once — expected. |
| AUTH-SESSION-003 | 401 | Your session has expired. | Idle timeout. |
| AUTH-SESSION-004 | 401 | Your session could not be verified on this device. | Device fingerprint mismatch: the token is being used from a different browser/device (or the fingerprint header is missing). |
| AUTH-SESSION-005 | 409 | Only one session is allowed at a time. | Single-session mode and another session is live. |
| AUTH-SESSION-006 | 500 | Sign-in is not available right now. | Signing key missing or the system user could not be resolved. WebHub configuration / DB. |
| AUTH-SESSION-007 | 403 | Sign-in is not allowed from this location. | IP / origin restriction (e.g. localhost not allowed). Used to be shown as "Account Disabled". |
| AUTH-SESSION-008 | 400 | Your browser did not provide the information needed to sign in. | Required header (fingerprint / cookie) missing. Usually a privacy extension or an old cached client. |
| AUTH-SESSION-009 | 404 | That session was not found. | Session management: the session id to revoke does not exist. |
Applies to Google, Apple, Microsoft, LinkedIn, X, Facebook, Instagram and the parts of Auth0 they share. The log line carries provider. On a callback failure the browser lands on /auth/<provider>?error=<code>&ref=….
| Code | Status | Public message | Meaning / what to check |
|---|---|---|---|
| AUTH-SSO-001 | 501 | This sign-in provider is not available on this system. | Provider not configured on the Hub (/api/oauth/exists). |
| AUTH-SSO-002 | 400 | The sign-in request could not be verified. | OAuth state failed: detail = expired, invalid, no-nonce, cookie-missing, cookie-mismatch. Cookie problems = third-party cookie blocking or the user opened the link in a different browser. |
| AUTH-SSO-003 | 400 | The sign-in provider did not return a valid response. | Callback had no code (user cancelled at the provider, or the provider sent an error — it is in detail). |
| AUTH-SSO-004 | 502 | We could not complete sign-in with the provider. | Token exchange failed. detail has the provider's error/error_description and HTTP status: bad client secret, wrong redirect URI, network. Configuration incident. |
| AUTH-SSO-005 | 401 | Your sign-in with the provider has expired. | ID token invalid/expired (detail has the jose reason). Clock skew on the server is a classic cause. |
| AUTH-SSO-006 | 400 | The email address on your provider account is not verified. | Provider says email_verified: false. User must verify with the provider. |
| AUTH-SSO-007 | 404 | No account is linked to this sign-in. | Provider identity verified, no IQX person matches. |
| AUTH-SSO-008 | 400 | More than one account matches this sign-in. | Duplicate people for that identity. |
| AUTH-SSO-009 | 403 | Your account does not have permission to sign in. | No LOGIN right. |
| AUTH-SSO-010 | 502 | We could not retrieve your profile from the provider. | Userinfo / /me call failed (detail has status + body). Provider outage or scope not granted. |
| AUTH-SSO-011 | 502 | We could not link the provider account. | Saving the provider id against the person failed (proc/DB). |
| Code | Status | Public message | Meaning / what to check |
|---|---|---|---|
| AUTH-AUTH0-001 | 500 | Sign-in is not fully configured on this system. | Management API credentials missing on the Hub. |
| AUTH-AUTH0-002 | 502 | We could not check your account with the sign-in provider. | Management API user lookup failed (detail has status/body). |
| AUTH-AUTH0-003 | 401 | Your registration session is no longer valid. | Registration cookie/state expired mid-wizard. User starts again. |
| AUTH-AUTH0-004 | 502 | We could not create your account with the sign-in provider. | Management API create-user failed. |
| AUTH-AUTH0-005 | 502 | We could not update your multi-factor settings. | MFA enrolment / reset call to Auth0 failed. |
| AUTH-AUTH0-006 | 400 | No person record was found for this registration. | Registration wizard: the person id in the token has no record. |
| AUTH-AUTH0-007 | 400 | This account is archived and cannot be registered. | Person is archived in IQX. |
| AUTH-AUTH0-008 | 400 | The person record has no email address. | Cannot create an Auth0 user without one. Fix the person record. |
| AUTH-AUTH0-009 | 403 | That multi-factor enrolment does not belong to your account. | Enrolment id / user id mismatch. Someone editing a URL, or a stale page. |
| AUTH-AUTH0-010 | 409 | An account with this email address already exists with the sign-in provider. | Auth0 already has that email (maybe under another connection). Link or delete it in Auth0. |
| AUTH-AUTH0-011 | 400 | The password is too weak for the sign-in provider. | Auth0 password policy rejected it. |
| AUTH-AUTH0-012 | 500 | Your account was created but sign-in could not be started. | The Auth0 user exists now but starting the session failed — do not let the user register again (AUTH0-010 would follow). Check the session log line by ref. |
| AUTH-AUTH0-013 | 400 | Your account is not linked to the sign-in provider. | Person has no Auth0 id yet (e.g. MFA management before first SSO sign-in). |
| AUTH-AUTH0-014 | 500 | Your account could not be created. | Unexpected failure in the registration flow. Sentry issue. |
| Code | Status | Public message | Meaning / what to check |
|---|---|---|---|
| AUTH-MAGIC-001 | 400 | This sign-in link is not valid. | Token missing or not 0x + 64 hex. Truncated by an email client — ask for the link as text. |
| AUTH-MAGIC-002 | 400 | This sign-in link was not found. | NetV2FetchMagicLink returned no row: never existed, already consumed, or purged. |
| AUTH-MAGIC-003 | 400 | This sign-in link has expired. | Row exists, past its expiry. |
| AUTH-MAGIC-004 | 400 | The account for this sign-in link is not available. | Person archived / not found. |
| AUTH-MAGIC-005 | 400 | More than one account matches this sign-in link. | Duplicate people. |
| AUTH-MAGIC-006 | 403 | Your account does not have permission to sign in. | No LOGIN right. |
| AUTH-MAGIC-007 | 400 | This sign-in link is for an action that is not recognised. | Action id not in NetV2MagicLinkActions — logged as warn; the raw id is still passed through. Add the action. |
| Code | Status | Public message | Meaning / what to check |
|---|---|---|---|
| AUTH-PASSKEY-001 | 400 | Passkey sign-in could not be started. | Options/challenge missing or expired (session lookup). |
| AUTH-PASSKEY-002 | 400 | This passkey is not recognised. | Credential id not stored for this user. |
| AUTH-PASSKEY-003 | 400 | Your passkey could not be verified. | simplewebauthn rejected the assertion; detail has the library reason plus the expected origin/rpID. An origin/rpID mismatch = the site is served from a hostname that differs from the configured RP. |
| AUTH-PASSKEY-004 | 400 | Your passkey could not be registered. | As above, for registration. |
| AUTH-PASSKEY-005 | 500 | Passkeys are not available right now. | RP configuration missing, or NetV2SavePasskeyOptions failed. |
| Code | Status | Public message | Meaning / what to check |
|---|---|---|---|
| AUTH-MFA-001 | 400 | Multi-factor authentication is not set up for your account. | No secret stored. |
| AUTH-MFA-002 | 401 | The verification code is not correct. | Wrong code. (The API still answers 200 { isValid: false } — the code is in the log.) Every user wrong forever = clock drift, or see HUB-001 "encryption secret changed?". |
| AUTH-MFA-003 | 500 | Multi-factor authentication could not be enabled. | Storing the secret failed. |
| Code | Status | Public message | Meaning / what to check |
|---|---|---|---|
| AUTH-HANDOFF-001 | 400 | The portal sign-in request is incomplete. | Token missing from the redeem call. |
| AUTH-HANDOFF-002 | 400 | The portal sign-in request could not be verified on this device. | Fingerprint missing/mismatch. |
| AUTH-HANDOFF-003 | 401 | The portal sign-in link is not valid or has expired. | detail says unknown, consumed, or expired-at <time>. |
| AUTH-HANDOFF-004 | 401 | This portal sign-in link has already been used. | Double redeem (two tabs, or a refresh). Harmless. |
| AUTH-HANDOFF-005 | 403 | Portal sign-in is not allowed from this location. | Origin not in the allowed list. |
| AUTH-HANDOFF-006 | 403 | This portal sign-in link is not valid for this site. | Token was created for another host. Wrong portal → site mapping. |
| Code | Status | Public message | Meaning / what to check |
|---|---|---|---|
| HUB-001 | 500 | The request could not be completed. | The Hub or a procedure answered with an IQXFailure we did not expect, or something the Hub gave us could not be used (e.g. MFA secret would not decrypt — "encryption secret changed?"). The Hub's message is in detail. Business-validation IQXFailures from a procedure are not Sentry issues. |
| HUB-002 | 503 | The IQX service is not available right now. | Hub / WebHub unreachable (connection refused, timeout, TLS). Incident. |
| HUB-003 | 502 | The request could not be completed. | Hub answered 5xx. First 300 chars of its reply are in detail. |
| HUB-004 | 401 | You must be signed in to do that. | Hub answered 401: an authenticated procedure was called without a bearer, or with one the Hub rejected. If it is a public proc, it needs the _ (anonymous) form. |
| HUB-005 | 403 | That action cannot be performed from the web. | Hub answered 403 — the procedure / route is not permitted for web callers. |
| HUB-006 | 404 | The requested action does not exist. | Procedure name unknown to the Hub or the database (detail has the name). Typo, or the SQL has not been deployed on that site. |
| HUB-007 | 400 | The request is missing required information. | Hub answered 400 — parameter missing/invalid; detail has the Hub's text. |
| Code | Status | Public message | Meaning / what to check |
|---|---|---|---|
| JOB-001 | 500 | The job failed. | The job threw. Its own console.error lines are in the webjob logger at warn. |
| JOB-002 | 400 | The job uses a module that is not approved. | require of a module outside the approved list. |
| JOB-003 | 504 | The job took too long and was stopped. | Exceeded its timeout. |
| JOB-004 | 500 | The job finished without producing a result. | Script returned without calling finish ( ). |
| Code | Status | Public message | Meaning / what to check |
|---|---|---|---|
| SYS-400 | 400 | The request could not be understood. | Fastify body/query validation, malformed JSON, or an invalid value to a settings route (detail says which). |
| SYS-401 | 401 | You are not signed in. | A legacy { status: 401 } throw with no more specific code. |
| SYS-403 | 403 | You do not have permission to do that. | User class check failed (detail has required vs actual), or a system token used on a user route. |
| SYS-404 | 404 | The requested resource was not found. | Unknown route. Never a Sentry issue. |
| SYS-429 | 429 | Too many requests. | Global rate limit. |
| SYS-500 | 500 | Something went wrong. | Unhandled exception — always a Sentry issue with the stack. The code to fix is wherever the stack points; if it recurs with a recognisable cause, give it a real code. |
| SYS-503 | 503 | The service is temporarily unavailable. | Server not ready (Mongo/DB down) or network failure from the browser (the client maps a failed fetch to this). |
| SYS-UNKNOWN | — | Something went wrong. | Client-side only: the response had no code (an old server, or a non-IQX proxy answered). The ref, if any, came from the header. |