# Web error codes 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** 1. In Sentry, search Issues or Logs for `request_id:` (or `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. 2. If the site has Sentry Logs switched off, the same line is on the server's stdout (`docker logs` / the Windows service log). Both WebHub nodes and the web server share the ref, so search all of them. 3. Find the code below. The table gives the public message, what it actually means, and what to check. 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. ## Severity, in one line 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. ## Password sign-in — `AUTH-PWD` | 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. | ## Account resolution — `AUTH-USER` | 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. | ## Self‑registration — `AUTH-REG` | 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. | ## Sessions and tokens — `AUTH-SESSION` | 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. | ## SSO (all providers) — `AUTH-SSO` 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/?error=&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). | ## Auth0-specific — `AUTH-AUTH0` | 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. | ## Magic links — `AUTH-MAGIC` | 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. | ## Passkeys — `AUTH-PASSKEY` | 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. | ## Multi-factor (TOTP) — `AUTH-MFA` | 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. | ## Portal handoff — `AUTH-HANDOFF` | 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