Authentication Errors
This page documents all authentication-related errors and how to handle them.
Error Response Schema
All authentication errors follow this standard format:
{
"error": {
"code": "ERROR_CODE",
"message": "Human-readable error message",
"status": 401,
"details": {
// Additional context (optional)
},
"documentation_url": "https://docs.chordian.ai/authentication/errors#error-code"
}
}HTTP Status Codes
200 OK
Authentication successful.
Response:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expiresIn": 1296000,
"refreshToken": "Set in httpOnly cookie"
}400 Bad Request
Missing or malformed request data.
Common Causes:
- Missing
usernameorpasswordfields - Invalid JSON format
- Missing refresh token cookie
Example Response:
{
"error": {
"code": "BAD_REQUEST",
"message": "No refresh token available",
"status": 400,
"details": {
"field": "refresh_token",
"issue": "Cookie not found in request"
}
}
}Solution:
- Verify request body format
- Ensure cookies are enabled and sent with request
- Check that all required fields are present
401 Unauthorized
Authentication failed or token invalid.
| Error Code | Description | Solution |
|---|---|---|
INVALID_CREDENTIALS | Wrong username/password | Check credentials and retry |
INVALID_TOKEN | Token signature invalid | Re-login to get new token |
TOKEN_EXPIRED | Session JWT expired | Refresh token or re-login |
INVALID_REFRESH_TOKEN | Refresh token invalid/expired | User must log in again |
NOT_AUTHENTICATED | No authentication provided | Include Authorization header |
Example Response:
{
"error": {
"code": "INVALID_TOKEN",
"message": "Token signature verification failed",
"status": 401,
"details": {
"reason": "Token has been tampered with or is malformed"
}
}
}Solution:
try:
response = requests.post(url, headers=headers)
response.raise_for_status()
except requests.exceptions.HTTPError as e:
if e.response.status_code == 401:
# Try to refresh token
refresh_response = requests.post('/api/auth/refresh')
if refresh_response.status_code == 200:
# Retry with new token
new_token = refresh_response.json()['token']
headers['Authorization'] = f'Bearer {new_token}'
response = requests.post(url, headers=headers)
else:
# Redirect to login
redirect_to_login()500 Internal Server Error
Server-side error during authentication.
Common Causes:
- Cognito service unavailable
- Database connection issue
- JWT signing key not configured
Example Response:
{
"error": {
"code": "INTERNAL_ERROR",
"message": "Login failed due to server error",
"status": 500,
"details": {
"request_id": "req_abc123def456"
}
}
}Solution:
- Retry with exponential backoff
- Check status page for incidents
- Contact support if persistent
Retry Logic:
async function loginWithRetry(credentials, maxRetries = 3) {
let lastError;
for (let i = 0; i < maxRetries; i++) {
try {
const response = await fetch('/api/auth/login', {
method: 'POST',
body: JSON.stringify(credentials)
});
if (response.ok) return response.json();
if (response.status === 500) {
// Wait with exponential backoff
const delay = Math.pow(2, i) * 1000; // 1s, 2s, 4s
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
throw new Error(`Login failed: ${response.status}`);
} catch (error) {
lastError = error;
}
}
throw lastError;
}502 Bad Gateway
Invalid response from AWS Cognito.
Example Response:
{
"error": {
"code": "BAD_GATEWAY",
"message": "Invalid response from authentication server",
"status": 502,
"details": {
"upstream": "AWS Cognito",
"request_id": "req_xyz789"
}
}
}Solution:
- Retry after a few seconds
- Check AWS Cognito service status
- Contact support if persistent
Error Handling Best Practices
1. Implement Exponential Backoff
import time
from requests.exceptions import HTTPError
def make_auth_request_with_retry(func, max_retries=3):
for attempt in range(max_retries):
try:
return func()
except HTTPError as e:
if e.response.status_code in [500, 502, 503]:
if attempt < max_retries - 1:
wait_time = (2 ** attempt) + random.uniform(0, 1)
time.sleep(wait_time)
continue
raise2. Handle Token Expiration
async function makeAuthenticatedRequest(endpoint, options) {
try {
const response = await fetch(endpoint, {
...options,
headers: {
...options.headers,
'Authorization': `Bearer ${getToken()}`
}
});
if (response.status === 401) {
// Try to refresh
const newToken = await refreshToken();
if (newToken) {
// Retry with new token
return makeAuthenticatedRequest(endpoint, options);
} else {
// Redirect to login
window.location.href = '/login';
}
}
return response;
} catch (error) {
console.error('Request failed:', error);
throw error;
}
}3. Log Errors for Debugging
try {
var response = client.execute(loginRequest);
// Handle response
} catch (IOException e) {
logger.error("Authentication failed",
"endpoint", loginRequest.getURI(),
"error", e.getMessage(),
"timestamp", Instant.now()
);
throw e;
}Common Scenarios
Scenario 1: Token Expired During Request
Detection:
401 Unauthorized with code: TOKEN_EXPIREDSolution:
- Call
/api/auth/refreshwith refresh token cookie - If refresh succeeds (200), retry original request with new token
- If refresh fails (401), redirect user to login page
Scenario 2: Refresh Token Expired
Detection:
401 Unauthorized from /api/auth/refresh
code: INVALID_REFRESH_TOKENSolution:
- Clear local storage and cookies
- Redirect user to login page
- Optionally show message: “Your session has expired. Please log in again.”
Scenario 3: Invalid Credentials
Detection:
401 Unauthorized from /api/auth/login
code: INVALID_CREDENTIALSSolution:
- Show user-friendly error message
- Don’t reveal which field was wrong (security)
- Implement rate limiting for login attempts
- After multiple failures, add CAPTCHA
Testing Authentication Errors
Use these test credentials (if sandbox available):
| Scenario | Username | Password | Expected Result |
|---|---|---|---|
| Success | test@example.com | ValidPass123! | 200 OK |
| Invalid credentials | test@example.com | wrongpass | 401 INVALID_CREDENTIALS |
| Expired token | Use expired JWT | - | 401 TOKEN_EXPIRED |