Error Codes
Every error Honeycluster can return, what it means, and how to react to it.

Honeycluster returns errors in a consistent envelope so clients can handle them uniformly:

Json
{
  "error": "rate_limited",
  "message": "Rate limit exceeded, retry after 27 seconds"
}

Non-error responses pass through the XRP Ledger's native JSON-RPC shape. The HTTP status code is chosen to match the class of failure; the body's error field is the machine-readable identifier.

Rate and capacity errors (4xx)
##
StatuserrorCauseFix
429
rate_limited
Shared-tier fair-use ceiling exceeded, or (private plans) project credit cap hit
Retry after the Retry-After seconds. Sustained traffic: upgrade tier.
402
payment_required
(Private plans) tier's cycle has ended with a negative balance
Settle balance from the portal.
Auth errors (4xx, private plans only)
##

These only appear on authenticated endpoints — the public cluster is keyless and never returns them.

StatuserrorCauseFix
401
unauthorized
Missing X-API-Key header on a private endpoint
Add the header.
401
invalid_key
Key is malformed or not recognized
Check you copied the full value from the portal.
401
revoked_key
Key exists but has been revoked
Issue a new key.
403
project_suspended
The project this key belongs to is suspended
Contact billing.
XRPL method errors (4xx)
##

The XRP Ledger validates method params before executing. These come through from rippled / Clio in the JSON-RPC envelope's result.error field, not the top-level error:

result.errorCauseFix
invalidParams
A required parameter is missing or malformed
Compare your call against the xrpl.org method reference.
lgrNotFound
Requested ledger doesn't exist or is outside history window
Verify the ledger index or switch to a full-history node (Honeycluster already uses Clio for history).
actNotFound
Account hasn't been activated on this ledger
Verify the address is correct and funded.
txnNotFound
Transaction hash not known to this server
Hash may be wrong, or the tx may not yet have been included in a validated ledger.

See xrpl.org's universal errors for the complete list.

Upstream errors (5xx)
##
StatuserrorCauseFix
502
upstream_unreachable
All regional nodes failed health checks during the request
Retry; the proxy will route to a different region.
503
upstream_degraded
Region is draining; traffic is failing over
Retry without delay.
504
upstream_timeout
Backend took longer than the request deadline
Retry; escalate if persistent.
500
internal_error
Unclassified server fault inside Honeycluster
Report via support with the X-Request-Id header.
Client error handling pattern
##

A resilient client distinguishes transient failures (retry) from terminal failures (abort):

TypeScript
async function call(body: unknown): Promise<unknown> {
  const res = await fetch('https://honeycluster.io', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(body),
  })

  if (res.ok) return res.json()

  const payload = await res.json().catch(() => ({ error: 'unknown' }))
  const code = payload?.error as string | undefined

  // Transient — retry with backoff
  if (['rate_limited', 'upstream_unreachable',
       'upstream_degraded', 'upstream_timeout'].includes(code ?? '')) {
    throw new RetryableError(code, res.headers.get('retry-after'))
  }

  // Terminal — don't retry
  throw new Error(`${code ?? 'unknown'}: ${payload?.message ?? res.statusText}`)
}

Every response includes an X-Request-Id header — pass it along in support requests so we can trace the failure through our logs.