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

# Errors and readiness

> Who is at fault, what to retry, and how to read /ready.

Every error is JSON with a closed `error` code, a `reason`, and the `quoteId` of the request when it got one:

```json theme={null}
{ "error": "declined", "reason": "no_route", "quoteId": "23e14e010000448f" }
```

The status says whose move it is:

| HTTP | Meaning | What to do |
| - | - | - |
| 400 | The request is wrong: a missing or malformed field, an address that is not base58, a quote that does not chain | Fix the request |
| 404 | No route for this pair under these filters, or an unknown path | Widen the filters or give up on the pair |
| 409 | The route went stale: a ticket expired, a venue was held out, a pool changed | Quote again |
| 413 | Body over 256 KiB | Send less |
| 422 | A named decline: the router knows why it will not serve this | Read `reason`; usually change the request or the pair |
| 503 | The router (or a chain read) is not ready | Retry with backoff |
| 500 | A bug | Report it with the `quoteId` |

Two error bodies differ from the shape above:

* `not_ready` carries a list, `reasons`, instead of `reason`;
* `low_liquidity` adds `liquidity: {venue, hubMint, hubAmount}`, the deepest pool the router found.

`quoteId` is absent when the body or query could not be parsed and on an unknown path. A failed build gets a new `quoteId`, not the quote's.

## Quote declines

| Status | `error` / `reason` | Meaning |
| - | - | - |
| 400 | `declined` / `zero_amount` | `amount` is 0 |
| 404 | `declined` / `no_route` | No route under these filters and hops |
| 404 | `declined` / `no_cycle` | Input equals output and no profitable cycle exists |
| 422 | `declined` / `cold_unresolved` | The router has never seen this mint and found no pool for it. Remembered for 10 minutes. |
| 422 | `declined` / `low_liquidity` | Only dust pools; see `liquidity` |
| 422 | `declined` / `transfer_guard` | A Token-2022 mint that is paused or has a transfer hook |
| 422 | `declined` / `stale` | A pool on the route is being re-read (after a restart or a stream gap). Retry in a moment. |
| 422 | `declined` / `unbuildable` | Every candidate route fails the build check (too many keys, a venue your config does not allow, …) |
| 422 | `declined` / `unservable`, `approx`, `incoherent`, `inactive`, `no_depth`, `missing_account`, `degenerate`, `unsupported` | The router cannot price the route exactly enough to serve it |
| 503 | `not_ready` | Not ready, or a cold token still being fetched (`miss gate busy`, `miss budget`, `clickhouse busy`) |

## Build declines

| Status | `error` / `reason` | Meaning |
| - | - | - |
| 400 | `quote_mismatch` | The body contradicts the quote (mints, or the platform fee) |
| 400 | `invalid_route_ticket`, `route_ticket_mismatch` | A ticket that does not verify, or does not match the body |
| 400 | `bad_recipient` | `destinationTokenAccount` is a token account, not a wallet |
| 400 | `declined` / `platform_fee` | See [Platform fee](/router/fees#when-a-fee-build-is-refused) |
| 409 | `route_expired` | The ticket is past its time to live |
| 409 | `venue_red` | A venue of the quoted route is now held out |
| 409 | `declined` / `pool_missing`, `satellite`, `layout`, `token_program`, `shared_account` | A pool account changed since the quote |
| 422 | `declined` / `unbuildable`, `exact_out_shape`, `wire_limit`, `wire`, `transfer_guard`, `program_hop_limit`, `compute_budget` | The route cannot become a transaction (over 64 keys or 4,096 bytes, over 1.4M compute units, …) |
| 422 | `declined` / `dark_trader` | SolFi V2 would charge this wallet a listed-trader fee: exclude that venue |
| 422 | `declined` / `<venue> has no live row in the swap on-chain config` | Your deploy does not allow that venue |
| 503 | `not_ready` / `swap is paused on chain` | Your deploy's config is paused |
| 503 | `not_ready` / `blockhash unavailable` | `serialize: true` without a fresh blockhash |
| 503 | `declined`, `rpc` | A chain read of the route's accounts or of the recipient failed |

A build decline's `reason` is a short label; the detail is in the router's log, under the same `quoteId`.

## `/ready`

`GET /ready` is `200 {"ready": true, "reasons": []}` when the router can quote and build, and `503` with every reason it cannot otherwise. Use it for your load balancer's health check; `GET /health` only says the process is up.

| Field | |
| - | - |
| `ready` | Whether quotes and builds are served |
| `reasons` | Every reason it is not. Human sentences, some in Italian: show them, do not parse them. |
| `warming` | After a restart, while pools are being re-read (2–6 minutes): quotes on pools not yet re-read decline `stale` |
| `red_pass` | Venues the price checks currently hold out, with why |
| `warnings` | Problems that do not stop serving |

What keeps a router red: no account stream yet, the index not built, your `swap` deploy's config unreadable or missing, the token directory not being written, a stalled stream. A paused config is not a readiness reason: the router stays ready and every build answers `503 swap is paused on chain`.

<Note>
  On a fresh install the router knows only the tokens traded since it started. A long-tail token never seen gives `422 cold_unresolved` on its first quote, until its first trade arrives or the background pool search finds it.
</Note>


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