Skip to main content

Handle Errors and Rate Limits

Learn how to handle common HTTP errors and rate limiting in Zen Mesh API calls.

What This Recipe Does

This recipe covers:

  1. Common HTTP status codes and their meanings
  2. Error response format
  3. How to handle 401/403/404/409/429/500 errors
  4. Retry strategies
  5. Using request IDs for troubleshooting

Error Response Format

All error responses follow this format:

{
"error": "ErrorType",
"message": "Human-readable error message",
"request_id": "req_abc123xyz"
}
FieldDescription
errorThe error type (e.g., ValidationError, Unauthorized)
messageDetailed explanation of the error
request_idUnique identifier for debugging and support

Common HTTP Status Codes

401 Unauthorized

Authentication failed. The API token is missing, invalid, or expired.

Example Response:

{
"error": "Unauthorized",
"message": "Invalid or expired API token",
"request_id": "req_xyz789"
}

How to Fix:

  1. Verify your API token in the Zen Mesh dashboard
  2. Ensure the ZEN_API_TOKEN environment variable is set correctly
  3. Test with a simple health check:
curl -sS -H "Authorization: Bearer *** $ZEN_API_BASE/health

403 Forbidden

You don't have permission to perform this action.

Example Response:

{
"error": "ForbiddenError",
"message": "You don't have permission to delete this plane",
"request_id": "req_abc123xyz"
}

How to Fix:

  1. Verify your token has the required permissions
  2. Check you're using the correct tenant ID
  3. Review token scopes/permissions in your dashboard

404 Not Found

The requested resource doesn't exist.

Example Response:

{
"error": "NotFoundError",
"message": "Plane not found: plane_dev_us_east_1",
"request_id": "req_abc123xyz"
}

How to Fix:

  1. Verify the resource ID is correct
  2. List resources first to see valid IDs:
curl -sS -H "Authorization: Bearer *** $ZEN_API_BASE/tenants/$ZEN_TENANT_ID/clusters

409 Conflict

The request conflicts with current server state.

Example Response:

{
"error": "ConflictError",
"message": "Plane already exists with this name",
"request_id": "req_abc123xyz"
}

How to Fix:

  1. Check if the resource already exists
  2. Use a unique name or ID
  3. Handle conflicts gracefully in your application

429 Too Many Requests

You've exceeded the rate limit for this endpoint.

Example Response:

{
"error": "RateLimitError",
"message": "Too many requests. Please try again in 60 seconds.",
"request_id": "req_abc123xyz"
}

How to Fix:

  1. Implement exponential backoff
  2. Check the Retry-After header when present:
    curl -sI "$ZEN_API_BASE/tenants/$ZEN_TENANT_ID/clusters" | grep Retry-After
  3. Reduce request rate

Retry Example (Python):

import time

def fetch_with_retry(url, max_retries=3):
for attempt in range(max_retries):
response = requests.get(url, headers={"Authorization": f"Bearer {token}"})

if response.status_code == 429:
retry_after = int(response.headers.get('Retry-After', 60))
time.sleep(retry_after)
continue

if response.ok:
return response

if attempt == max_retries - 1:
response.raise_for_status()

500 Internal Server Error

An unexpected error occurred on the server.

Example Response:

{
"error": "InternalServerError",
"message": "An unexpected error occurred while processing your request",
"request_id": "req_abc123xyz"
}

How to Fix:

  1. Retry the request (with backoff)
  2. Check if request_id is present - include it when contacting support:
    I'm getting a 500 error.
    Request ID: req_abc123xyz
    Endpoint: POST /tenants/{tenant_id}/clusters
  3. Check status.zen-mesh.io for service status

503 Service Unavailable

The service is temporarily unavailable.

Example Response:

{
"error": "ServiceUnavailableError",
"message": "Service is temporarily unavailable. Please try again later.",
"request_id": "req_abc123xyz"
}

How to Fix:

  1. Wait and retry
  2. Check service status page
  3. Contact support for planned maintenance

Using Request IDs for Troubleshooting

When contacting support, always include the request_id from the error response. This helps support quickly identify the specific request and logs.

Example support message:

I'm getting a 500 Internal Server Error when creating a plane.

Request ID: req_abc123xyz
Endpoint: POST /tenants/{tenant_id}/clusters
Request body: {"name": "plane_dev", ...}

Rate Limiting Strategy

Exponential Backoff

Use progressive delays between retries:

import time

def exponential_backoff_retry(url, max_retries=5, base_delay=1):
for attempt in range(max_retries):
response = requests.get(url, headers={"Authorization": f"Bearer {token}"})

if response.ok:
return response

if response.status_code == 429:
delay = base_delay * (2 ** attempt)
time.sleep(delay)
continue

response.raise_for_status()

Request Batching

Batch similar requests to reduce rate limit hits:

# Instead of:
for plane_id in plane_ids:
requests.get(f"{base_url}/tenants/{tenant_id}/clusters/{plane_id}")

# Do:
plane_list = requests.get(f"{base_url}/tenants/{tenant_id}/clusters").json()
for plane in plane_list['clusters']:
print(plane['id'])

Next Steps


Full API Reference: API Overview

More Information: Authentication | Common Errors