Skip to content

Error Codes

This reference documents all error codes returned by the License Monitor API with troubleshooting guidance.

All API errors follow a consistent JSON format:

{
"error": "Error Category",
"code": "ERROR_CODE",
"message": "Human-readable error description",
"details": "Additional context if available",
"requestId": "req-abc123",
"timestamp": "2024-01-15T10:30:45.123Z"
}
CodeMeaningDescription
200OKRequest successful
201CreatedResource created
204No ContentSuccess with no response body
CodeMeaningCommon Causes
400Bad RequestInvalid JSON, missing required fields
401UnauthorizedMissing or invalid API key
403ForbiddenValid key but insufficient permissions
404Not FoundEndpoint or resource doesn’t exist
405Method Not AllowedWrong HTTP method
409ConflictResource conflict
422Unprocessable EntityValidation error
429Too Many RequestsRate limit exceeded
CodeMeaningCommon Causes
500Internal Server ErrorUnexpected server error
502Bad GatewayUpstream service unavailable
503Service UnavailableServer overloaded or maintenance
504Gateway TimeoutUpstream timeout
CodeHTTPDescriptionResolution
AUTH_MISSING401No API key providedInclude X-API-Key header
AUTH_INVALID401Invalid API keyVerify API key is correct
AUTH_EXPIRED401API key expiredGenerate new API key
AUTH_REVOKED401API key revokedContact administrator
AUTH_INSUFFICIENT403Insufficient permissionsUse key with proper permissions
CodeHTTPDescriptionResolution
INVALID_JSON400Malformed JSON bodyCheck JSON syntax
MISSING_FIELD400Required field missingInclude required field
INVALID_FIELD400Field value invalidCheck field value type/format
INVALID_QUERY400Invalid query parameterCheck parameter syntax
BODY_TOO_LARGE413Request body too largeReduce payload size
CodeHTTPDescriptionResolution
NOT_FOUND404Resource not foundVerify resource ID/path
ALREADY_EXISTS409Resource already existsUse different identifier
CONFLICT409Resource conflictResolve conflict
GONE410Resource deletedResource no longer available
CodeHTTPDescriptionResolution
RATE_LIMIT_EXCEEDED429Too many requestsWait and retry
QUOTA_EXCEEDED429Daily/monthly quota exceededUpgrade plan or wait
CodeHTTPDescriptionResolution
INTERNAL_ERROR500Unexpected errorReport issue with requestId
DATABASE_ERROR500Database operation failedRetry or report
UPSTREAM_ERROR502License server unavailableCheck license server status
SERVICE_UNAVAILABLE503Service temporarily unavailableRetry later
TIMEOUT504Operation timed outRetry or increase timeout
CodeHTTPDescriptionResolution
LICENSE_SERVER_UNREACHABLE502Cannot connect to license serverCheck server connectivity
LICENSE_QUERY_FAILED500License query returned errorCheck server logs
LICENSE_PARSE_ERROR500Cannot parse license outputReport parsing issue
COMMAND_EXECUTION_FAILED500Command execution failedCheck command and permissions
COMMAND_TIMEOUT504Command timed outIncrease timeout or simplify command
interface ApiError {
error: string;
code: string;
message: string;
details?: string;
requestId: string;
timestamp: string;
}
async function fetchWithErrorHandling(url: string, options: RequestInit = {}) {
const response = await fetch(url, options);
if (!response.ok) {
const error: ApiError = await response.json();
switch (error.code) {
case 'AUTH_MISSING':
case 'AUTH_INVALID':
throw new Error('Authentication required. Please provide a valid API key.');
case 'RATE_LIMIT_EXCEEDED':
const retryAfter = response.headers.get('Retry-After');
throw new Error(`Rate limited. Retry after ${retryAfter} seconds.`);
case 'LICENSE_SERVER_UNREACHABLE':
throw new Error('License server is not reachable. Please check connectivity.');
default:
throw new Error(`API Error: ${error.message} (${error.code})`);
}
}
return response.json();
}
import requests
class ApiError(Exception):
def __init__(self, code, message, request_id):
self.code = code
self.message = message
self.request_id = request_id
super().__init__(f"{code}: {message}")
def api_request(url, headers=None):
response = requests.get(url, headers=headers)
if not response.ok:
error = response.json()
if error['code'] == 'RATE_LIMIT_EXCEEDED':
retry_after = response.headers.get('Retry-After', 60)
raise ApiError(
error['code'],
f"Rate limited. Retry after {retry_after}s",
error['requestId']
)
raise ApiError(
error['code'],
error['message'],
error['requestId']
)
return response.json()

These errors are safe to retry:

CodeRetry Strategy
RATE_LIMIT_EXCEEDEDWait for Retry-After header
SERVICE_UNAVAILABLEExponential backoff
TIMEOUTRetry with same timeout
UPSTREAM_ERRORRetry after delay
DATABASE_ERRORRetry after short delay

These errors require action before retrying:

CodeRequired Action
AUTH_MISSINGAdd authentication
AUTH_INVALIDFix API key
INVALID_JSONFix request body
MISSING_FIELDAdd required field
NOT_FOUNDVerify resource exists
async function retryWithBackoff<T>(
fn: () => Promise<T>,
maxRetries: number = 3,
baseDelay: number = 1000
): Promise<T> {
let lastError: Error;
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await fn();
} catch (error) {
lastError = error;
// Check if error is retryable
if (!isRetryable(error)) {
throw error;
}
// Calculate delay with jitter
const delay = baseDelay * Math.pow(2, attempt) * (0.5 + Math.random() * 0.5);
await new Promise(resolve => setTimeout(resolve, delay));
}
}
throw lastError;
}
function isRetryable(error: any): boolean {
const retryableCodes = [
'RATE_LIMIT_EXCEEDED',
'SERVICE_UNAVAILABLE',
'TIMEOUT',
'UPSTREAM_ERROR',
'DATABASE_ERROR'
];
return retryableCodes.includes(error.code);
}

Every response includes a requestId for debugging:

Terminal window
# Include request ID when reporting issues
curl -v http://localhost:8080/api/health
# Response headers
< X-Request-ID: req-abc123def456
# Error response body
{
"requestId": "req-abc123def456",
...
}

Use the request ID to find related logs:

Terminal window
grep "req-abc123def456" /var/log/license-monitor/license_monitor.log