# Errors and retries

> What each status means, which errors to retry, and the errors of quote and build.

Error bodies come in four shapes; see [Conventions](/guides/conventions/#error-bodies). Log `error ?? message`, and keep the `x-request-id` header of every failed response.

## By status

| Status | Means | Retry? |
|---|---|---|
| `400` | Fix the request. On a quote, a size error carries a `minSrcAmount` you can use directly. | After fixing it |
| `401`, `403` | Missing key, unknown key, or a problem with your account's configuration. | No. Contact Khalani |
| `404` | Unknown order, or the same asset on both sides. A plain-text `404 Not Found` means the path is wrong: check the `/v2` prefix. | No |
| `409` | The quote expired (build), the size is too large (quote, with `maxSrcAmount` or `maxOutcomeAmount`), or the order is not published yet (cancel). | Quote again, or wait |
| `429` | Rate limited. No `Retry-After`. | Yes, with backoff |
| `500` | Server error. | Once, then contact Khalani with the `x-request-id` |
| `501` | This deployment cannot take deposits from the source chain. | No |
| `502` | A chain read or dependent service failed (build), or the cancel was rejected (cancel). | Build: back off and retry at most once. Cancel: read the order and rejection first |
| `503` | Temporarily unavailable: maintenance (`Retry-After: 300`), pricing, or no solver capacity in this direction. | Yes, with a capped backoff |

Some `503`s clear on their own and some need Khalani to fix configuration. The response does not tell them apart, so cap your retries.

When you contact Khalani, include the `orderId` if there is one, the `x-request-id` of the failing response, and the time of the call.

## Quote errors

| Status | `error` | What to do |
|---|---|---|
| `400` | Validation body | Wrong amount for the `mode`, unknown `mode`, or a malformed amount. Fix the request. |
| `400` | `Unsupported source token …` / `Unsupported destination token …` | The token is not listed for that chain. Check `GET /v2/params`. |
| `400` | `Requested amount is below what the solver will fill`, `Requested amount is too small to deliver one destination base unit` | Quote again at or above `detail.minSrcAmount`. |
| `400` | `Deposit is at or below the flat fee, so nothing would be published` | Quote again at or above `detail.minSrcAmount`. It clears only the flat fee, so follow the next refusal's figure if there is one. |
| `404` | `Source and destination resolve to the same mToken` | Both sides are the same asset. |
| `409` | `Requested amount exceeds what the solver can fill` | Quote again at or below `detail.maxSrcAmount` or `detail.maxOutcomeAmount`. |
| `503` | `The solver cannot serve this direction right now` | Nothing is fillable in this direction right now. Back off and try later without changing the size. |
| `503` | `The solver could not price this direction` | Pricing failed or returned an inconsistent answer. Retry. |
| `503` | `This pair is not priced for v2 quoting right now`, `No USD price available for …`, `V2 pricing is not configured …`, `USD price for … is stale …` | The flat fee cannot be priced. The API never assumes a 1:1 price. Retry with a capped backoff, and contact Khalani if it persists. |
| `503` | `Integrator terms are temporarily unreadable` | Retry. |

## Build errors

Validation errors occur before order creation. A `500` or `502` can occur after a TRON deposit address was reserved or an order record was written; cleanup is not guaranteed. Do not treat these responses as usable deposit plans or fund an order found after a failed build without confirming it with Khalani. Back off and retry at most once, then contact Khalani with the `x-request-id`. Repeated retries can exhaust the deposit-address pool.

| Status | `error` | What to do |
|---|---|---|
| `400` | Validation body, or `{ "message": "Malformed JSON body" }` | Missing or malformed field, bad address, unknown chain, or a body that is not JSON. Fix the request. |
| `400` | `Unsupported source token …` / `Unsupported destination token …` | Check `GET /v2/params`. |
| `400` | `Deposit is at or below the flat fee, so nothing would be published` | Quote first to learn the minimum. |
| `400` | `Computed publishedOutcome is zero — amount below the minimum economic threshold` | The amount is too small to produce any output. |
| `400` | `Quoted terms do not match the signature — re-quote` | A field of `quote.build` was changed. Send it unchanged. |
| `400` | `payoutAddr is required for destination chain …` / `refundAddr is required for source chain …` | A non-EVM side needs an explicit recipient. |
| `400` | `<field> is not an activated Tron account; …` | Fund the TRON address once before using it. |
| `400` | `Address <addr> is not a valid recipient on chain <id>` | Malformed `payoutAddr` or `refundAddr` for that chain. |
| `404` | `Source and destination resolve to the same mToken` | Same asset on both sides. |
| `409` | `Quoted terms expired at <expiresAt>` | Quote again and build with the new quote. Nothing was stored. |
| `500` | `Failed to persist pending order`, `Operator signing unavailable`, or an unhandled error | Back off and retry at most once, then contact Khalani. State may remain after the failed build. |
| `502` | `Failed to quote deposit relay fee`, `Failed to read chain head for order tracking`, `Failed to read spoke token allowance`, `Failed to verify the Tron recipient account`, `Failed to reserve a deposit address`, `Failed to start order tracking` | Back off and retry at most once, then contact Khalani. A reservation or tracking failure may leave stored state. |
| `503` | `Integrator terms are temporarily unreadable`, `This pair is not priced for v2 right now`, `No USD price available for …`, `V2 pricing is not configured …` | Nothing was stored. Retry with a capped backoff. |

Both quote and build also return the maintenance `503` and the rate-limit `429`; see [Rate limits and reliability](/guides/rate-limits/). Errors for cancels are in [Cancel and refunds](/guides/cancel-and-refunds/#cancel-errors).
