> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bloklake.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Errors

> Every error code, when it happens and what to do.

Errors are a non-`200` status with a JSON body:

```json theme={null}
{"error": {"code": "invalid_query", "message": "unknown key \"addr\" in logs[0]"}}
```

Use `code` in your program; `message` is for people and may change.

## Request errors

| Status | Code | When | What to do |
| - | - | - | - |
| `400` | `invalid_query` | the body is malformed, too large, has an unknown key or field, a wrong-length hex value, or inconsistent options | fix the request; the message names the problem |
| `400` | `unknown_query_id` | the `queryId` expired (30 minutes after last use) or was registered on another chain | resend the full filter |
| `404` | `unknown_set` | a set id that doesn't exist for your project on this chain (expired or never created) | create the set again and retry |
| `403` | `quota_exceeded` | creating a set past 50 sets or 50 MiB per project, while every set was used in the last 10 minutes | delete sets you no longer need |

## Key and billing errors

| Status | Code | When | What to do |
| - | - | - | - |
| `401` | `missing_api_key` | no key sent (`WWW-Authenticate: Bearer` is set) | send `Authorization: Bearer <key>` |
| `401` | `invalid_api_key` | the key doesn't exist | check the key |
| `401` | `key_revoked` | the key was deleted or rotated, or its subscription ended | use a current key |
| `403` | `key_suspended` | subscription payment overdue past the 5-day grace period | update the payment method |
| `402` | `balance_exhausted` | pay-as-you-go balance used up | top up; the message links to the page |
| `402` | `overage_limit_reached` | the subscription used its included data plus its overage limit this period | an admin raises the limit, or wait for the next period |

## Rate limits

| Status | Code | When | What to do |
| - | - | - | - |
| `429` | `rate_limited` | over the key's requests per second (`Retry-After: 1`) | wait and retry |
| `429` | `too_many_in_flight` | too many of the key's requests still open on this chain | finish reading a response, then retry |
| `429` | `set_rate_limited` | creating sets faster than 1,000,000 values per minute per project | wait `Retry-After` seconds |
| `429` | `key_blocked` | the key kept sending about 10× its limit or more; blocked for 5 minutes on every chain | wait `Retry-After` seconds; slow down |
| `429` | `ip_rate_limited` | over 100 requests per second from one address | wait and retry |
| `429` | `ip_blocked` | the address kept exceeding that, or sent over 30 requests with missing or unknown keys in a minute; blocked 10 minutes | wait `Retry-After` seconds |

## Server errors

| Status | Code | When | What to do |
| - | - | - | - |
| `503` | `unavailable` | the chain's server is busy: no query slot freed within 5 seconds (`Retry-After: 1`) | retry with backoff |
| `503` | `auth_unavailable` | the key service is briefly unreachable and your key isn't cached (`Retry-After: 1`) | retry with backoff |
| `500` | `internal` | a server-side error | retry a few times; report it with the `X-Request-Id` if it persists |

Server errors and refused requests (`401`, `402`, `403` key errors, `429`) are never billed.
Requests rejected by validation are billed the 10 KB minimum. See
[How billing works](https://docs.bloklake.com/billing/how-billing-works.md#whats-free).

## Errors during a response

Once a `200` response has started, an error can't be reported in the body: the server closes the
connection instead. Treat an unexpected end of the body, or fewer rows than `bl.objects`, as a
failed request and retry. See [Errors and retries](https://docs.bloklake.com/production/errors-and-retries.md#failures-in-the-middle-of-a-response).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.