--- 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.