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 username or password fields
  • 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 CodeDescriptionSolution
INVALID_CREDENTIALSWrong username/passwordCheck credentials and retry
INVALID_TOKENToken signature invalidRe-login to get new token
TOKEN_EXPIREDSession JWT expiredRefresh token or re-login
INVALID_REFRESH_TOKENRefresh token invalid/expiredUser must log in again
NOT_AUTHENTICATEDNo authentication providedInclude 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
            raise

2. 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_EXPIRED

Solution:

  1. Call /api/auth/refresh with refresh token cookie
  2. If refresh succeeds (200), retry original request with new token
  3. If refresh fails (401), redirect user to login page

Scenario 2: Refresh Token Expired

Detection:

401 Unauthorized from /api/auth/refresh
code: INVALID_REFRESH_TOKEN

Solution:

  • 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_CREDENTIALS

Solution:

  • 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):

ScenarioUsernamePasswordExpected Result
Successtest@example.comValidPass123!200 OK
Invalid credentialstest@example.comwrongpass401 INVALID_CREDENTIALS
Expired tokenUse expired JWT-401 TOKEN_EXPIRED

Next Steps