---
title: Error handling
description: Which status codes mean stop, which mean retry, and what the quote rejections actually say.
---
Errors are gRPC statuses. The code tells you whether to retry; the message tells you why.
| Code | Meaning | Retry |
| --- | --- | --- |
| `INVALID_ARGUMENT` | The request is wrong. | No, not unchanged. |
| `UNAVAILABLE` | The operator cannot serve this right now. | Yes, with backoff. |
| `RESOURCE_EXHAUSTED` | Rate limited. | Yes, after backing off; the point budget refills continuously. |
| `UNAUTHENTICATED` | Missing, unknown, or disabled credential. | No. |
| `NOT_FOUND` | No such quote, order, or token. | No. |
| `FAILED_PRECONDITION` | The request is fine but the state does not allow it. | No, not until the state changes. |
| `INTERNAL` | Operator-side failure. | Yes, sparingly. |
## Quote rejections
These come back as `INVALID_ARGUMENT`. The request needs to change before it will succeed.
| Message | Cause |
| --- | --- |
| `unsupported pair` | That source and destination combination is not quotable. Same token to itself on one chain also lands here. |
| `invalid amount` | `amount` is not a positive decimal string in base units. |
| `invalid trade_type` | `trade_type` is missing, `TRADE_TYPE_UNSPECIFIED`, or unknown. |
| `slippage too high` | An expected-output quote with slippage of 100% or more; no input can be solved. |
| `guaranteed output is not supported for this pair` | A guaranteed trade type on a same-chain swap or a route with a swap leg or cross-asset lane. Retry with the corresponding target type. |
| `invalid address` | `recipient` or `refund_address` is malformed for its chain. |
| `amount below minimum of N usd` | Trade size under the floor. |
| `amount above maximum of N usd` | Trade size over the ceiling. |
| `amount is too small to cover fees required for this order` | The committed fees would consume the whole deposit. |
| `invalid referrer list` | A referrer address is unusable, or the basis points are out of range. |
| `swap quotes unsupported on destination chain` | The destination has no aggregator configured for the requested token, or a same-chain swap was requested on Solana. |
| `gas drop exceeds the allowed maximum` | Over the chain's `max_gas_drop`. |
| `gasless is not supported for this order` | `gasless: true` on a same-chain swap, a native source token, or a chain without gasless deposits. |
| `quote is not a source swap` | `GetSwapInstructions` was called for a quote with no source swap leg. |
## Temporary conditions
These come back as `UNAVAILABLE`. The same request may succeed shortly after, so retry with backoff rather than surfacing a hard failure.
| Message | Cause |
| --- | --- |
| `quote disabled for chain` | Quoting is turned off for that chain right now. |
| `insufficient inventory` | Not enough float on the destination to cover the trade. Retrying smaller often works immediately. |
| `bridge pair suspended` | The cross-asset lane is paused, typically on a depeg or exposure limit. |
| `price unavailable` | The price feed is stale or missing for one of the assets. |
| `fee unbounded` | Fees could not be bounded, typically from missing gas data. |
| `aggregator error` | The routing aggregator failed or returned no route. |
`insufficient inventory` is a size problem, not an outage. If your interface can suggest a smaller amount, that is a better response than an error.
## Auth and limits
| Message | Code | Fix |
| --- | --- | --- |
| `unknown api key` | `UNAUTHENTICATED` | The key does not exist. Check for a copy error. |
| `api key disabled` | `UNAUTHENTICATED` | The key was revoked. Create a new one. |
| `rate limit exceeded` | `RESOURCE_EXHAUSTED` | Back off; the point budget refills continuously. Keyed budgets are far higher than keyless ones. |
| `missing session token` | `UNAUTHENTICATED` | A `PartnerApi` call without a bearer token. |
| `invalid or expired session` | `UNAUTHENTICATED` | Sign in again. |
| `sponsor_fees requires an api key` | `UNAUTHENTICATED` | Send the request with your `x-api-key`. |
| `quote is not gasless` | `FAILED_PRECONDITION` | `SubmitGaslessOrder` for a quote not requested with `gasless: true`. |
| `insufficient funding balance` | `FAILED_PRECONDITION` | Top up through the partner panel or `BuildPartnerFunding`. |
## Retry policy
```ts
const RETRYABLE = new Set([Code.Unavailable, Code.ResourceExhausted]);
const withRetry = async (call: () => Promise, attempts = 3): Promise => {
for (let i = 0; ; i++) {
try {
return await call();
} catch (e) {
if (i >= attempts - 1 || !RETRYABLE.has(ConnectError.from(e).code)) throw e;
await new Promise((r) => setTimeout(r, 2 ** i * 500));
}
}
};
```
Retry reads freely. Do not retry `GetQuote` in a tight loop to force inventory to appear; it is rate limited and the answer will not change within a second.
## Failures after the deposit
Once a deposit lands, nothing surfaces as an API error. Failure is expressed as order state instead: the order routes to a refund, or to one of the terminal failure states. Handle those in the tracking path, not in error handling. See [Order lifecycle](/concepts/order-lifecycle).
## Reverts on chain
| Revert | Cause |
| --- | --- |
| `InsufficientOutput` | A swap returned less than the committed minimum. |
| `AggregatorNotAllowed` | The aggregator in the calldata is not allowlisted. Refetch `GetSwapInstructions`. |
| `SwapFailed` | The aggregator call itself failed, usually stale routing calldata. |
| `InvalidMsgValue` | Transaction value does not match what the call expects. |
| `EnforcedPause` | The contract is paused. |
| `GasDropNotAllowed` | A gas drop was requested where it is not permitted. |
| `InvalidReferrerBps` | `referrerBps` on a same-chain swap is above the contract cap. |
Stale swap calldata is the most common one. Fetch instructions immediately before sending, not at quote time.