Error Code Reference
All errors thrown by the Calimatic Auth SDK are instances of CalimaticAuthError. This class exposes three properties:
| Property | Type | Description |
|---|
status | number | HTTP status code returned by the API |
code | AuthErrorCodeValue | Machine-readable error code (one of the values below) |
message | string | Human-readable error description |
Usage
import { CalimaticAuthError, AuthErrorCode } from '@calimatic/auth-sdk';
try {
await client.auth.login({ email, password });
} catch (err) {
if (err instanceof CalimaticAuthError) {
switch (err.code) {
case AuthErrorCode.INVALID_CREDENTIALS:
// wrong email or password
break;
case AuthErrorCode.ACCOUNT_LOCKED:
// too many failed attempts
break;
default:
console.error(err.code, err.message);
}
}
}
Authentication Errors
INVALID_CREDENTIALS
| |
|---|
| HTTP Status | 401 |
| Trigger | The email or password provided did not match any active account. |
| Troubleshooting | Verify the email address and password are correct. Check for leading/trailing whitespace. |
| Thrown by | auth.login |
ACCOUNT_LOCKED
| |
|---|
| HTTP Status | 423 |
| Trigger | The account has been temporarily locked due to too many consecutive failed login attempts. |
| Troubleshooting | Wait for the lockout to expire (check security.lockoutStatus() for remaining time), or call security.unlock() from an admin client. |
| Thrown by | auth.login |
INVALID_CLIENT
| |
|---|
| HTTP Status | 401 |
| Trigger | The x-client-id or x-client-secret headers are missing, unknown, or do not match a registered app client. |
| Troubleshooting | Verify the clientId and clientSecret in your HeadlessAuthConfig match the app client registered in the Calimatic Auth developer portal. |
| Thrown by | All endpoints (every request requires valid client credentials) |
INVALID_TOKEN
| |
|---|
| HTTP Status | 401 |
| Trigger | The Bearer access token provided is expired or otherwise invalid. |
| Troubleshooting | Refresh the token via auth.refresh(), or provide an onRefresh callback when constructing the client to enable automatic retry. |
| Thrown by | mfa.status, mfa.enroll, mfa.confirmEnrollment, mfa.disable, mfa.backupCodes.count, mfa.backupCodes.regenerate |
TOKEN_EXPIRED
| |
|---|
| HTTP Status | 401 |
| Trigger | The refresh token is expired or has been explicitly revoked. |
| Troubleshooting | The user must log in again with auth.login() to obtain a new refresh token. |
| Thrown by | auth.refresh, auth.logout |
EMAIL_NOT_VERIFIED
| |
|---|
| HTTP Status | 403 (login blocked) |
| Trigger | Login was attempted but the user's email address has not yet been verified. |
| Troubleshooting | Call email.sendVerification() to resend the verification link, then prompt the user to check their inbox. |
| Thrown by | auth.login |
MFA Errors
MFA_REQUIRED
| |
|---|
| HTTP Status | N/A (200 response with mfaRequired: true) |
| Trigger | Login succeeded but the user has MFA enrolled — a challenge token is issued instead of access tokens. This is not an error; it is part of the normal step-up flow. |
| Troubleshooting | Check 'mfaRequired' in result after auth.login(). If true, call mfa.verify() with the mfaToken and a TOTP code or backup code. |
| Thrown by | Not thrown as an error — returned as MfaChallengeResponse from auth.login |
MFA_INVALID_CODE
| |
|---|
| HTTP Status | 401 |
| Trigger | The TOTP code or backup code provided was incorrect. |
| Troubleshooting | Verify the code is current (TOTP codes expire every 30 seconds). If using a backup code, ensure it has not already been used. |
| Thrown by | mfa.verify, mfa.confirmEnrollment, mfa.disable, mfa.backupCodes.regenerate |
MFA_CHALLENGE_EXPIRED
| |
|---|
| HTTP Status | 401 |
| Trigger | The mfaToken received from auth.login() has expired before mfa.verify() was called. MFA tokens are short-lived (typically 5 minutes). |
| Troubleshooting | Restart the login flow — call auth.login() again to obtain a fresh MFA challenge token. |
| Thrown by | mfa.verify |
MFA_ALREADY_ENROLLED
| |
|---|
| HTTP Status | 409 |
| Trigger | An attempt was made to enroll TOTP when the user already has MFA enabled. |
| Troubleshooting | Call mfa.disable() first if re-enrollment is needed, then call mfa.enroll() again. |
| Thrown by | mfa.enroll |
MFA_NOT_ENROLLED
| |
|---|
| HTTP Status | 400 |
| Trigger | An MFA operation (verify, disable, backup codes) was attempted but the user has not enrolled TOTP. |
| Troubleshooting | Call mfa.enroll() followed by mfa.confirmEnrollment() to set up TOTP before attempting this operation. |
| Thrown by | mfa.disable, mfa.backupCodes.count, mfa.backupCodes.regenerate |
Request Errors
VALIDATION_ERROR
| |
|---|
| HTTP Status | 400 |
| Trigger | The request body failed server-side Zod schema validation (e.g., missing required field, invalid email format, password too short). |
| Troubleshooting | Check the error.message property for the specific field that failed validation. Ensure all required fields are present and correctly typed. |
| Thrown by | All endpoints that accept a request body |
USER_NOT_FOUND
| |
|---|
| HTTP Status | 404 |
| Trigger | The userId provided does not correspond to any user in the platform database. |
| Troubleshooting | Verify the userId is correct. The user may have been deleted, or you may be using the wrong ID format (must be a UUID). |
| Thrown by | sessions.list, sessions.revoke, sessions.revokeAll, security.lockoutStatus, security.unlock |
CONFLICT
| |
|---|
| HTTP Status | 409 |
| Trigger | A resource already exists that would conflict with the requested operation (e.g., email address already registered during signup, or session already inactive). |
| Troubleshooting | Check whether the resource already exists before creating it. For signup, the user may need to log in instead. |
| Thrown by | auth.signup |
RATE_LIMITED
| |
|---|
| HTTP Status | 429 |
| Trigger | Too many requests have been made from this client in a short window. |
| Troubleshooting | Back off and retry using exponential delay. The Retry-After response header (when present) indicates when the client may retry. |
| Thrown by | All endpoints |
Server Errors
INTERNAL_ERROR
| |
|---|
| HTTP Status | 500 |
| Trigger | An unexpected error occurred on the server (e.g., database failure, Keycloak unreachable). |
| Troubleshooting | Retry the request. If the error persists, contact the Calimatic platform team. |
| Thrown by | All endpoints |
UNKNOWN
| |
|---|
| HTTP Status | Varies |
| Trigger | The server returned an error response that could not be mapped to a known AuthErrorCode. This should be rare. |
| Troubleshooting | Check error.message for details. If this is reproducible, report it — it may indicate a missing error mapping. |
| Thrown by | All endpoints (fallback) |
Error Code Summary
| Code | HTTP Status | Category |
|---|
INVALID_CREDENTIALS | 401 | Authentication |
ACCOUNT_LOCKED | 423 | Authentication |
INVALID_CLIENT | 401 | Authentication |
INVALID_TOKEN | 401 | Authentication |
TOKEN_EXPIRED | 401 | Authentication |
EMAIL_NOT_VERIFIED | 403 | Authentication |
MFA_REQUIRED | 200 (not an error) | MFA |
MFA_INVALID_CODE | 401 | MFA |
MFA_CHALLENGE_EXPIRED | 401 | MFA |
MFA_ALREADY_ENROLLED | 409 | MFA |
MFA_NOT_ENROLLED | 400 | MFA |
VALIDATION_ERROR | 400 | Request |
USER_NOT_FOUND | 404 | Request |
CONFLICT | 409 | Request |
RATE_LIMITED | 429 | Request |
INTERNAL_ERROR | 500 | Server |
UNKNOWN | Varies | Server |