Errors and Status Codes
This document provides a complete reference for HTTP status codes and error responses in the Fluree API.
Error Response Format
fluree-server errors return a consistent JSON structure:
{
"error": "Human-readable error description",
"status": 400,
"@type": "err:db/BadRequest",
"cause": {
"error": "Optional nested cause",
"status": 400,
"@type": "err:db/JsonParse"
}
}
Fields:
error: Human-readable error message (primary diagnostic text)status: HTTP status code (numeric)@type: Compact error type IRI (stable, machine-readable category)cause: Optional nested cause chain (only present for select errors)
Stability note: clients (including the Fluree CLI) may pattern-match on substrings within the error field for targeted hints, so error messages should be stable across releases.
HTTP Status Codes
Success Codes (2xx)
200 OK
The request succeeded.
Used for:
- Successful queries
- Successful transactions
- Successful GET requests
Example:
{
"t": 5,
"timestamp": "2024-01-22T10:30:00.000Z",
"commit_id": "bafybeig...commitT5"
}
201 Created
A new resource was created.
Used for:
- Ledger creation
- Index creation
Example:
{
"ledger_id": "mydb:main",
"created": "2024-01-22T10:00:00.000Z"
}
204 No Content
Request succeeded with no response body.
Used for:
- DELETE operations
- Administrative commands
Client Error Codes (4xx)
400 Bad Request
The request is malformed or contains invalid data.
Common Causes:
- Invalid JSON syntax
- Invalid JSON-LD structure
- Invalid SPARQL syntax
- Invalid IRI format
- Type mismatch
Error typing:
The server includes a compact error type IRI in the @type field. This is the
preferred stable, machine-readable category for programmatic handling.
Example:
{
"error": "Invalid JSON: expected value at line 5, column 12",
"status": 400,
"@type": "err:db/JsonParse"
}
How to Fix:
- Validate JSON syntax
- Check IRI formats
- Verify JSON-LD structure
- Review the
errormessage and optionalcause
401 Unauthorized
Authentication is required but not provided or invalid.
Common Causes:
- Missing authentication credentials
- Invalid API key
- Expired JWT token
- Invalid signature (for signed requests)
Example:
{
"error": "Bearer token required",
"status": 401,
"@type": "err:db/Unauthorized"
}
How to Fix:
- Provide valid authentication credentials
- Check API key or token
- Renew expired tokens
- Verify signature process for signed requests
403 Forbidden
Authentication succeeded but authorization failed.
Common Causes:
- Insufficient permissions for operation
- Policy denies access
- Ledger access restricted
Example:
{
"error": "access denied (403)",
"status": 403,
"@type": "err:db/Forbidden"
}
How to Fix:
- Verify user has required permissions
- Check policy configuration
- Contact administrator for access
404 Not Found
The requested resource doesn't exist.
Common Causes:
- Ledger doesn't exist
- Entity not found
- Endpoint doesn't exist
Example:
{
"error": "Ledger not found: mydb:main",
"status": 404,
"@type": "err:db/LedgerNotFound"
}
How to Fix:
- Verify ledger name spelling
- Check if ledger was created
- Verify entity IRI
408 Request Timeout
The request took too long to process.
Common Causes:
- Query timeout exceeded
- Complex query taking too long
- Database under heavy load
Example:
{
"error": "Query execution exceeded timeout",
"status": 408,
"@type": "err:db/Timeout"
}
How to Fix:
- Simplify query
- Add more specific filters
- Use LIMIT clause
- Increase timeout setting
- Check server load
409 Conflict
The request conflicts with current server state.
Common Causes:
- Concurrent modification conflict
- Ledger already exists
- Resource state conflict
Example:
{
"error": "Ledger already exists: mydb:main",
"status": 409,
"@type": "err:db/LedgerExists"
}
How to Fix:
- Use different ledger name
- Handle concurrent modifications with retry logic
- Check resource state before modifying
413 Payload Too Large
The request or response exceeds size limits.
Common Causes:
- Transaction too large
- Query result too large
- Request body exceeds limit
Example:
{
"error": "request body exceeds configured limit",
"status": 413,
"@type": "err:db/PayloadTooLarge"
}
How to Fix:
- Split large transactions into batches
- Use LIMIT clause for queries
- Use pagination for large result sets
- Increase size limits (if appropriate)
415 Unsupported Media Type
The Content-Type is not supported.
Common Causes:
- Wrong Content-Type header
- Unsupported format
- Missing Content-Type header
Example:
{
"error": "Content-Type not supported: text/plain",
"status": 415,
"@type": "err:db/UnsupportedMediaType"
}
How to Fix:
- Set correct Content-Type header
- Use supported format
- Check API documentation for supported types
422 Unprocessable Entity
The request is well-formed but semantically invalid.
Common Causes:
- Invalid data values
- Business rule violation
- Semantic constraint violation
Example:
{
"error": "semantic constraint violation",
"status": 422,
"@type": "err:db/ConstraintViolation"
}
How to Fix:
- Validate data before submitting
- Check business rules
- Review constraint requirements
429 Too Many Requests
Rate limit exceeded.
Common Causes:
- Too many requests in time window
- Exceeded quota
Example:
{
"error": "rate limit exceeded",
"status": 429,
"@type": "err:db/RateLimited"
}
Response Headers:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1642857645
Retry-After: 45
How to Fix:
- Wait before retrying (check Retry-After header)
- Implement exponential backoff
- Reduce request rate
- Request higher rate limit
Server Error Codes (5xx)
500 Internal Server Error
An unexpected error occurred on the server.
Common Causes:
- Unhandled exception
- Database error
- Internal logic error
Example:
{
"error": "internal error",
"status": 500,
"@type": "err:db/Internal"
}
How to Fix:
- Check server logs
- Report to system administrator
- Retry request
- Contact support if persists
502 Bad Gateway
Error communicating with upstream service.
Common Causes:
- Storage backend unavailable
- Nameservice unavailable
- Network error
Example:
{
"error": "upstream service error",
"status": 502,
"@type": "err:db/BadGateway"
}
How to Fix:
- Check storage backend status
- Verify network connectivity
- Check AWS/cloud service status
- Retry with backoff
503 Service Unavailable
The server is temporarily unavailable.
Common Causes:
- Server overloaded
- Maintenance mode
- Resource exhaustion
Example:
{
"error": "service unavailable",
"status": 503,
"@type": "err:db/ServiceUnavailable"
}
Response Headers:
Retry-After: 300
How to Fix:
- Wait and retry (check Retry-After header)
- Implement retry logic with exponential backoff
- Check service status page
504 Gateway Timeout
Upstream service didn't respond in time.
Common Causes:
- Storage backend timeout
- Long-running query
- Network latency
Example:
{
"error": "gateway timeout",
"status": 504,
"@type": "err:db/GatewayTimeout"
}
How to Fix:
- Retry request
- Check storage backend performance
- Simplify query
- Increase timeout settings
Error Handling Best Practices
1. Always Check Status Codes
Check HTTP status before parsing response:
const response = await fetch(url, options);
if (!response.ok) {
const err = await response.json();
// err.error is the primary human-readable message, err["@type"] is the stable category.
throw new Error(`${err["@type"] || "err:unknown"}: ${err.error}`);
}
2. Implement Retry Logic
Retry transient errors with exponential backoff:
async function retryRequest(fn, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await fn();
} catch (err) {
if (!isRetryable(err) || i === maxRetries - 1) {
throw err;
}
await sleep(Math.pow(2, i) * 1000);
}
}
}
function isRetryable(err) {
return [408, 429, 502, 503, 504].includes(err.status);
}
3. Handle Rate Limits
Respect rate limit headers:
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After');
await sleep(retryAfter * 1000);
return retryRequest(fn);
}
4. Log Error Details
Log complete error context for debugging:
console.error({
status: response.status,
error: errorData.error,
error_type: errorData["@type"],
cause: errorData.cause,
requestId: response.headers.get('X-Request-ID')
});
5. User-Friendly Messages
Show appropriate messages to users:
function getUserMessage(error) {
switch (error["@type"]) {
case 'err:db/LedgerNotFound':
return 'Database not found. Please check the name.';
case 'err:db/Timeout':
return 'Query took too long. Please try a simpler query.';
case 'err:db/RateLimited':
return 'Too many requests. Please wait a moment.';
default:
return 'An error occurred. Please try again.';
}
}
6. Graceful Degradation
Handle errors gracefully:
try {
const data = await query(ledger);
return data;
} catch (err) {
if (err["@type"] === 'err:db/LedgerNotFound') {
// Create ledger and retry
await createLedger(ledger);
return await query(ledger);
}
throw err;
}
7. Circuit Breaker Pattern
Prevent cascading failures:
class CircuitBreaker {
constructor(threshold = 5, timeout = 60000) {
this.failures = 0;
this.threshold = threshold;
this.timeout = timeout;
this.state = 'CLOSED';
}
async execute(fn) {
if (this.state === 'OPEN') {
throw new Error('Circuit breaker is OPEN');
}
try {
const result = await fn();
this.onSuccess();
return result;
} catch (err) {
this.onFailure();
throw err;
}
}
onSuccess() {
this.failures = 0;
this.state = 'CLOSED';
}
onFailure() {
this.failures++;
if (this.failures >= this.threshold) {
this.state = 'OPEN';
setTimeout(() => {
this.state = 'HALF_OPEN';
this.failures = 0;
}, this.timeout);
}
}
}
Related Documentation
- Overview - API overview
- Endpoints - API endpoints
- Signed Requests - Authentication
- Troubleshooting - General troubleshooting
- Common Errors - Common error solutions