All errors follow a consistent JSON structure:
Error information Machine-readable error code (uppercase with underscores)
Human-readable error description
Additional error context (field-specific errors, validation failures, etc.)
Response metadata Unique request identifier for debugging
Example Error Response
curl -X POST "http://localhost:8080/users" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"email": "invalid-email"}'
{
"error" : {
"code" : "VALIDATION_ERROR" ,
"message" : "validation failed" ,
"details" : {
"email" : "invalid email format" ,
"name" : "field is required"
}
},
"meta" : {
"request_id" : "f8a9b0c1d2e3"
}
}
HTTP Status Codes
Permission Mongo uses standard HTTP status codes:
Success Codes (2xx)
Code Description Usage 200 OKSuccess GET, PUT, PATCH, DELETE operations 201 CreatedResource created POST operations 202 AcceptedRequest accepted Async operations 204 No ContentSuccess with no response body DELETE operations
Client Error Codes (4xx)
Code Description Error Code 400 Bad RequestInvalid request format BAD_REQUEST401 UnauthorizedMissing or invalid authentication UNAUTHORIZED, INVALID_TOKEN, EXPIRED_TOKEN403 ForbiddenInsufficient permissions FORBIDDEN, INVALID_PERMISSION404 Not FoundResource not found NOT_FOUND, COLLECTION_NOT_FOUND, DOCUMENT_NOT_FOUND, VERSION_NOT_FOUND409 ConflictResource conflict CONFLICT, RESOURCE_EXISTS422 Unprocessable EntityValidation error VALIDATION_ERROR, SCHEMA_VALIDATION_ERROR429 Too Many RequestsRate limit exceeded RATE_LIMIT_EXCEEDED
Server Error Codes (5xx)
Code Description Error Code 500 Internal Server ErrorServer error INTERNAL_ERROR503 Service UnavailableService temporarily unavailable SERVICE_UNAVAILABLE
Error Codes
All error codes defined in the API:
Authentication Errors
UNAUTHORIZED
Status : 401 Unauthorized
Cause : Missing or invalid authorization header
Example :
curl -X GET "http://localhost:8080/users"
{
"error" : {
"code" : "UNAUTHORIZED" ,
"message" : "missing authorization header"
},
"meta" : {
"request_id" : "a1b2c3d4e5f6"
}
}
INVALID_TOKEN
Status : 401 Unauthorized
Cause : JWT token is malformed, has invalid signature, or wrong algorithm
{
"error" : {
"code" : "INVALID_TOKEN" ,
"message" : "invalid token signature"
},
"meta" : {
"request_id" : "b2c3d4e5f6a7"
}
}
EXPIRED_TOKEN
Status : 401 Unauthorized
Cause : JWT token has expired (past exp claim)
{
"error" : {
"code" : "EXPIRED_TOKEN" ,
"message" : "token has expired"
},
"meta" : {
"request_id" : "c3d4e5f6a7b8"
}
}
Authorization Errors
FORBIDDEN
Status : 403 Forbidden
Cause : User doesn’t have permission to perform this action
Example :
curl -X DELETE "http://localhost:8080/users/507f1f77bcf86cd799439011" \
-H "Authorization: Bearer USER_TOKEN"
{
"error" : {
"code" : "FORBIDDEN" ,
"message" : "insufficient permissions"
},
"meta" : {
"request_id" : "d4e5f6a7b8c9"
}
}
INVALID_PERMISSION
Status : 403 Forbidden
Cause : Permission check failed (RBAC rules deny access)
{
"error" : {
"code" : "INVALID_PERMISSION" ,
"message" : "user cannot delete documents in this collection"
},
"meta" : {
"request_id" : "e5f6a7b8c9d0"
}
}
Resource Errors
NOT_FOUND
Status : 404 Not Found
Cause : Resource doesn’t exist
Example :
curl -X GET "http://localhost:8080/users/invalid_id" \
-H "Authorization: Bearer YOUR_TOKEN"
{
"error" : {
"code" : "NOT_FOUND" ,
"message" : "resource not found"
},
"meta" : {
"request_id" : "f6a7b8c9d0e1"
}
}
DOCUMENT_NOT_FOUND
Status : 404 Not Found
Cause : Specific document doesn’t exist in collection
{
"error" : {
"code" : "DOCUMENT_NOT_FOUND" ,
"message" : "document not found in collection 'users'"
},
"meta" : {
"request_id" : "a7b8c9d0e1f2"
}
}
COLLECTION_NOT_FOUND
Status : 404 Not Found
Cause : Collection doesn’t exist or not configured
{
"error" : {
"code" : "COLLECTION_NOT_FOUND" ,
"message" : "collection 'unknown_collection' not found"
},
"meta" : {
"request_id" : "b8c9d0e1f2a3"
}
}
VERSION_NOT_FOUND
Status : 404 Not Found
Cause : Document version doesn’t exist
{
"error" : {
"code" : "VERSION_NOT_FOUND" ,
"message" : "version 5 not found for document"
},
"meta" : {
"request_id" : "c9d0e1f2a3b4"
}
}
Validation Errors
BAD_REQUEST
Status : 400 Bad Request
Cause : Malformed request (invalid JSON, missing required headers, etc.)
Example :
curl -X POST "http://localhost:8080/users" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: text/plain" \
-d 'not json'
{
"error" : {
"code" : "BAD_REQUEST" ,
"message" : "content-type must be application/json"
},
"meta" : {
"request_id" : "d0e1f2a3b4c5"
}
}
VALIDATION_ERROR
Status : 422 Unprocessable Entity
Cause : Request validation failed (schema validation, field constraints, etc.)
Example :
curl -X POST "http://localhost:8080/users" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"email": "not-an-email"}'
{
"error" : {
"code" : "VALIDATION_ERROR" ,
"message" : "validation failed" ,
"details" : {
"email" : "invalid email format" ,
"name" : "field is required" ,
"age" : "must be greater than 0"
}
},
"meta" : {
"request_id" : "e1f2a3b4c5d6"
}
}
SCHEMA_VALIDATION_ERROR
Status : 422 Unprocessable Entity
Cause : Document doesn’t match collection schema
{
"error" : {
"code" : "SCHEMA_VALIDATION_ERROR" ,
"message" : "document does not match schema" ,
"details" : {
"field" : "created_at" ,
"expected" : "date" ,
"received" : "string"
}
},
"meta" : {
"request_id" : "f2a3b4c5d6e7"
}
}
Conflict Errors
CONFLICT
Status : 409 Conflict
Cause : Resource conflict (e.g., concurrent update)
{
"error" : {
"code" : "CONFLICT" ,
"message" : "resource has been modified"
},
"meta" : {
"request_id" : "a3b4c5d6e7f8"
}
}
RESOURCE_EXISTS
Status : 409 Conflict
Cause : Resource with unique identifier already exists
Example :
curl -X POST "http://localhost:8080/users" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"email": "[email protected] "}'
{
"error" : {
"code" : "RESOURCE_EXISTS" ,
"message" : "user with email '[email protected] ' already exists"
},
"meta" : {
"request_id" : "b4c5d6e7f8a9"
}
}
Rate Limiting Errors
RATE_LIMIT_EXCEEDED
Status : 429 Too Many Requests
Cause : Too many requests from client (see Rate Limits )
{
"error" : {
"code" : "RATE_LIMIT_EXCEEDED" ,
"message" : "rate limit exceeded, try again later"
},
"meta" : {
"request_id" : "c5d6e7f8a9b0"
}
}
Server Errors
INTERNAL_ERROR
Status : 500 Internal Server Error
Cause : Unexpected server error
{
"error" : {
"code" : "INTERNAL_ERROR" ,
"message" : "internal server error"
},
"meta" : {
"request_id" : "d6e7f8a9b0c1"
}
}
When you encounter an INTERNAL_ERROR, use the request_id to search server logs for details.
SERVICE_UNAVAILABLE
Status : 503 Service Unavailable
Cause : Service temporarily unavailable (database down, maintenance, etc.)
{
"error" : {
"code" : "SERVICE_UNAVAILABLE" ,
"message" : "service temporarily unavailable"
},
"meta" : {
"request_id" : "e7f8a9b0c1d2"
}
}
Error Details
The details field provides additional context for errors:
Validation Error Details
{
"error" : {
"code" : "VALIDATION_ERROR" ,
"message" : "validation failed" ,
"details" : {
"email" : "invalid email format" ,
"age" : "must be between 0 and 150" ,
"roles" : "array must contain at least one item"
}
}
}
Schema Error Details
{
"error" : {
"code" : "SCHEMA_VALIDATION_ERROR" ,
"message" : "document does not match schema" ,
"details" : {
"field" : "metadata.tags" ,
"reason" : "expected array, got string"
}
}
}
Best Practices
Check Status Code : Always check HTTP status code first
Use Error Codes : Parse the error.code field for programmatic handling
Log Request IDs : Save request_id for debugging and support
Handle All Error Types : Implement handlers for all error codes
User-Friendly Messages : Show error.message to users
Retry Logic : Implement exponential backoff for 5xx errors
Validation : Show error.details for validation failures
Example Error Handling
JavaScript/TypeScript
async function fetchUser ( userId : string ) {
try {
const response = await fetch ( `http://localhost:8080/users/ ${ userId } ` , {
headers: {
'Authorization' : `Bearer ${ token } ` ,
},
});
if ( ! response . ok ) {
const errorData = await response . json ();
switch ( errorData . error . code ) {
case 'UNAUTHORIZED' :
case 'EXPIRED_TOKEN' :
// Redirect to login
redirectToLogin ();
break ;
case 'NOT_FOUND' :
case 'DOCUMENT_NOT_FOUND' :
// Show not found message
showError ( 'User not found' );
break ;
case 'FORBIDDEN' :
// Show permission denied
showError ( 'You do not have permission to view this user' );
break ;
case 'INTERNAL_ERROR' :
// Log and show generic error
console . error ( 'Request ID:' , errorData . meta . request_id );
showError ( 'An error occurred. Please try again later.' );
break ;
default :
console . error ( 'Unhandled error:' , errorData . error . code );
showError ( errorData . error . message );
}
return null ;
}
return await response . json ();
} catch ( error ) {
console . error ( 'Network error:' , error );
showError ( 'Network error. Please check your connection.' );
return null ;
}
}
Python
import requests
def fetch_user ( user_id : str , token : str ):
try :
response = requests.get(
f 'http://localhost:8080/users/ { user_id } ' ,
headers = { 'Authorization' : f 'Bearer { token } ' }
)
if not response.ok:
error_data = response.json()
error_code = error_data[ 'error' ][ 'code' ]
request_id = error_data[ 'meta' ][ 'request_id' ]
if error_code in [ 'UNAUTHORIZED' , 'EXPIRED_TOKEN' ]:
# Handle authentication error
raise AuthenticationError( 'Please log in again' )
elif error_code in [ 'NOT_FOUND' , 'DOCUMENT_NOT_FOUND' ]:
# Handle not found
raise NotFoundError( 'User not found' )
elif error_code == 'FORBIDDEN' :
# Handle permission error
raise PermissionError ( 'Insufficient permissions' )
elif error_code == 'INTERNAL_ERROR' :
# Log and raise
print ( f 'Internal error, request_id: { request_id } ' )
raise ServerError( 'Server error occurred' )
else :
# Handle unknown error
raise APIError(error_data[ 'error' ][ 'message' ])
return response.json()
except requests.RequestException as e:
print ( f 'Network error: { e } ' )
raise NetworkError( 'Network error occurred' )
Debugging
Request ID Tracking
Every error includes a request_id in the meta field. Use this to:
Search server logs
Trace request through distributed systems
Report issues to support
Debug in production
Server Logs
Server logs include structured information:
{
"timestamp" : "2026-03-04T10:15:30Z" ,
"level" : "error" ,
"request_id" : "d6e7f8a9b0c1" ,
"method" : "POST" ,
"path" : "/users" ,
"status" : 422 ,
"error" : "validation failed" ,
"details" : {
"email" : "invalid email format"
}
}