Skip to main content

Error Codes

All API errors follow a consistent format and include helpful information for debugging.

Error Response Format

{
"error": "ErrorType",
"message": "Human-readable error description",
"code": "ERROR_CODE",
"details": { ... }
}

HTTP Status Codes

StatusDescription
200Success
201Created
204No Content
400Bad Request
401Unauthorized
403Forbidden
404Not Found
409Conflict
422Unprocessable Entity
429Too Many Requests
500Internal Server Error
503Service Unavailable

Authentication Errors

401 Unauthorized

Missing Authentication:

{
"error": "Unauthorized",
"message": "Authentication required",
"code": "AUTH_REQUIRED"
}

Invalid Token:

{
"error": "Unauthorized",
"message": "Invalid or expired token",
"code": "INVALID_TOKEN"
}

Invalid API Key:

{
"error": "Unauthorized",
"message": "Invalid API key",
"code": "INVALID_API_KEY"
}

Expired Token:

{
"error": "Unauthorized",
"message": "Token has expired",
"code": "TOKEN_EXPIRED"
}

403 Forbidden

Insufficient Permissions:

{
"error": "Forbidden",
"message": "You don't have permission to perform this action",
"code": "INSUFFICIENT_PERMISSIONS",
"details": {
"required": "admin",
"current": "viewer"
}
}

Server Access Denied:

{
"error": "Forbidden",
"message": "You don't have access to this server",
"code": "SERVER_ACCESS_DENIED",
"details": {
"server_id": "550e8400-e29b-41d4-a716-446655440000"
}
}

Feature Not Available:

{
"error": "Forbidden",
"message": "This feature requires a Pro license",
"code": "FEATURE_NOT_AVAILABLE",
"details": {
"feature": "siem",
"required_tier": "pro",
"current_tier": "personal"
}
}

Validation Errors

400 Bad Request

Invalid JSON:

{
"error": "Bad Request",
"message": "Invalid JSON in request body",
"code": "INVALID_JSON"
}

Missing Required Field:

{
"error": "Bad Request",
"message": "Missing required field: ip",
"code": "MISSING_FIELD",
"details": {
"field": "ip"
}
}

422 Unprocessable Entity

Validation Failed:

{
"error": "Validation Error",
"message": "Request validation failed",
"code": "VALIDATION_FAILED",
"details": {
"errors": [
{
"field": "ip",
"message": "Invalid IP address format"
},
{
"field": "maxretry",
"message": "Must be a positive integer"
}
]
}
}

Invalid IP Address:

{
"error": "Validation Error",
"message": "Invalid IP address: 999.999.999.999",
"code": "INVALID_IP",
"details": {
"ip": "999.999.999.999"
}
}

Invalid CIDR:

{
"error": "Validation Error",
"message": "Invalid CIDR notation",
"code": "INVALID_CIDR",
"details": {
"value": "10.0.0.0/99"
}
}

Resource Errors

404 Not Found

Resource Not Found:

{
"error": "Not Found",
"message": "Server not found",
"code": "RESOURCE_NOT_FOUND",
"details": {
"resource": "server",
"id": "550e8400-e29b-41d4-a716-446655440000"
}
}

409 Conflict

Duplicate Entry:

{
"error": "Conflict",
"message": "IP already exists in whitelist",
"code": "DUPLICATE_ENTRY",
"details": {
"ip": "10.0.0.0/8",
"existing_id": 1
}
}

Username Taken:

{
"error": "Conflict",
"message": "Username already taken",
"code": "USERNAME_TAKEN",
"details": {
"username": "admin"
}
}

Rate Limiting

429 Too Many Requests

{
"error": "Too Many Requests",
"message": "Rate limit exceeded",
"code": "RATE_LIMITED",
"details": {
"limit": 100,
"remaining": 0,
"reset_at": "2024-01-15T10:31:00Z",
"retry_after": 60
}
}

Headers included:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1705320660
Retry-After: 60

Server Errors

500 Internal Server Error

{
"error": "Internal Server Error",
"message": "An unexpected error occurred",
"code": "INTERNAL_ERROR",
"details": {
"request_id": "req-abc123"
}
}

503 Service Unavailable

{
"error": "Service Unavailable",
"message": "Database connection failed",
"code": "SERVICE_UNAVAILABLE",
"details": {
"retry_after": 30
}
}

License Errors

Server Limit Reached:

{
"error": "Forbidden",
"message": "Server limit reached for your license",
"code": "SERVER_LIMIT_REACHED",
"details": {
"limit": 3,
"current": 3,
"tier": "personal"
}
}

License Expired:

{
"error": "Forbidden",
"message": "Your license has expired",
"code": "LICENSE_EXPIRED",
"details": {
"expired_at": "2024-01-01T00:00:00Z"
}
}

Command Errors

Command Failed:

{
"error": "Command Error",
"message": "Command execution failed",
"code": "COMMAND_FAILED",
"details": {
"command_id": "cmd-abc123",
"exit_code": 1,
"output": "fail2ban-client: error: ..."
}
}

Command Timeout:

{
"error": "Command Error",
"message": "Command timed out",
"code": "COMMAND_TIMEOUT",
"details": {
"command_id": "cmd-abc123",
"timeout_seconds": 60
}
}

Integration Errors

AbuseIPDB Error:

{
"error": "Integration Error",
"message": "AbuseIPDB API error",
"code": "ABUSEIPDB_ERROR",
"details": {
"api_error": "Rate limit exceeded"
}
}

Discord Webhook Error:

{
"error": "Integration Error",
"message": "Failed to send Discord notification",
"code": "DISCORD_ERROR",
"details": {
"http_status": 401,
"message": "Invalid webhook URL"
}
}

Error Code Reference

CodeDescription
AUTH_REQUIREDAuthentication is required
INVALID_TOKENToken is invalid
INVALID_API_KEYAPI key is invalid
TOKEN_EXPIREDToken has expired
INSUFFICIENT_PERMISSIONSUser lacks required permissions
SERVER_ACCESS_DENIEDUser cannot access this server
FEATURE_NOT_AVAILABLEFeature requires higher license tier
INVALID_JSONRequest body is not valid JSON
MISSING_FIELDRequired field is missing
VALIDATION_FAILEDRequest validation failed
INVALID_IPInvalid IP address format
INVALID_CIDRInvalid CIDR notation
RESOURCE_NOT_FOUNDRequested resource not found
DUPLICATE_ENTRYEntry already exists
USERNAME_TAKENUsername is already in use
RATE_LIMITEDRate limit exceeded
INTERNAL_ERRORInternal server error
SERVICE_UNAVAILABLEService temporarily unavailable
SERVER_LIMIT_REACHEDLicense server limit reached
LICENSE_EXPIREDLicense has expired
COMMAND_FAILEDRemote command failed
COMMAND_TIMEOUTCommand execution timed out
ABUSEIPDB_ERRORAbuseIPDB integration error
DISCORD_ERRORDiscord webhook error
SMTP_ERROREmail sending error
SIEM_ERRORSIEM integration error

Handling Errors

Best Practices

  1. Check HTTP status code first - Determines error category
  2. Parse error response - Get detailed error information
  3. Use error codes - For programmatic error handling
  4. Log request_id - For debugging with support
  5. Implement retry logic - For transient errors (5xx, 429)

Example Error Handler

async function apiCall(url, options) {
const response = await fetch(url, options);

if (!response.ok) {
const error = await response.json();

switch (error.code) {
case 'AUTH_REQUIRED':
case 'INVALID_TOKEN':
case 'TOKEN_EXPIRED':
// Redirect to login
break;
case 'RATE_LIMITED':
// Wait and retry
const retryAfter = error.details.retry_after;
await sleep(retryAfter * 1000);
return apiCall(url, options);
case 'VALIDATION_FAILED':
// Show validation errors to user
break;
default:
// Log and show generic error
console.error('API Error:', error);
}

throw new Error(error.message);
}

return response.json();
}