> For the complete documentation index, see [llms.txt](https://docs.swapkit.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.swapkit.dev/spotlights/route-availability-and-size-limits.md).

# Route availability and providers errors

A route can be missing from a `/v3/quote` response for two different kinds of reason: it was removed before any provider was asked, or a provider was asked and declined.

The first kind — naming, availability, size ceilings — produces no `providerErrors` entry at all, and is covered in §1–§3. The second reports itself, with a code you can act on; those are listed in §4.

### 1. The provider name must match

Provider identifiers are exact. `GET /providers` is the authoritative list; a name that does not appear there is silently ignored.

The common surprise is the streaming variants. `THORCHAIN` and `MAYACHAIN` are **not** served — the listed names are `THORCHAIN_STREAMING` and `MAYACHAIN_STREAMING`. A request sending `providers: ["THORCHAIN"]` matches nothing and returns `noRoutesFound`.

A provider can also be listed but fully switched off globally or for your key. `GET /providers` reports it with an empty `enabledChainIds`, and `GET /providers/status` shows every chain under `disabledChainsGlobal`. In that state no size and no pair will quote.

### 2. Availability can be directional

A provider that is live on a chain in one direction is not necessarily live in the other. Harbor's TRON support is currently buy-side only: swaps *into* TRON quote normally, swaps *out of* TRON are closed to general aggregation and open only on explicit request.

| Request                         | Harbor TRON sell |
| ------------------------------- | ---------------- |
| no `providers` field            | dropped          |
| `providers: ["HARBOR"]`         | **served**       |
| `providers: ["HARBOR", "NEAR"]` | dropped          |

The single-provider requirement is deliberate. Integrators that send a full provider list on every request would otherwise pass through the gate without intending to, which defeats the point of having one.

One detail worth knowing: the gate opens only when exactly one name is left in your list after switched-off providers are removed. Every other name stays in, even one that has no chance of serving your pair — `["HARBOR", "ONEINCH"]` is still two names, so Harbor stays hidden. Don't rely on this; it shifts as soon as a provider's status changes.

### 3. A route can have a size ceiling

Some routes have a maximum sell size — usually newer ones we are still running at low volume. A request above the limit is dropped like an unsupported pair, with no "amount too large" error, because the route is removed before any provider is asked. Limits are in USD on the sell value and apply in both directions; below the limit, quoting is normal.

Limits change, and partner deployments may have their own. Find the working size at runtime instead of hard-coding it, and tell us if one is blocking volume you need.

### Telling them apart

These causes are hard to tell apart from the response alone. The discriminator is cheap: re-quote the same pair at a smaller size.

| Symptom                                                           | Cause                                                                   | Where to look                               |
| ----------------------------------------------------------------- | ----------------------------------------------------------------------- | ------------------------------------------- |
| Provider absent from `GET /providers`                             | naming ([§1](#id-1.-the-provider-name-must-match))                      | `GET /providers`                            |
| Present but `enabledChainIds` is empty                            | provider switched off ([§1](#id-1.-the-provider-name-must-match))       | `GET /providers/status`                     |
| Present and enabled, but a smaller amount quotes fine             | a size ceiling ([§3](#id-3.-a-route-can-have-a-size-ceiling))           | contact us                                  |
| Present and enabled, no amount works, the reverse direction works | directional availability ([§2](#id-2.-availability-can-be-directional)) | retry with that provider alone              |
| No amount works in either direction                               | pair genuinely not served                                               | the provider's asset list via `GET /tokens` |

### 4. A provider was asked and declined

These are the opposite case to §1–§3: the route existed, the provider was asked, and it said no. Each one arrives as a `providerErrors` entry on a **`200`** response — the quote itself succeeded.

Each entry falls into one of three handling classes:

* **Fix the request** — the input is wrong or too small. Retrying unchanged will fail again.
* **Retry** — transient provider or network failure. The same request may succeed shortly after.
* **Route elsewhere** — that provider can't serve this pair, or is halted. Use another route from `routes`.

<table><thead><tr><th width="230">Error code</th><th width="200">Providers observed</th><th>What it means</th><th width="150">What to do</th></tr></thead><tbody><tr><td><code>sellAssetAmountTooSmall</code></td><td><code>THORCHAIN_STREAMING</code>, <code>MAYACHAIN_STREAMING</code>, <code>CHAINFLIP</code> (+ streaming), <code>NEAR</code>, <code>HARBOR</code>, <code>FLASHNET</code></td><td>Below the provider's minimum.</td><td><strong>Fix the request.</strong> Read <code>minAmount</code> and retry at or above it.</td></tr><tr><td><code>insufficientLiquidity</code></td><td><code>CHAINFLIP</code> (+ streaming), <code>NEAR</code>, <code>HARBOR</code>, <code>GARDEN</code></td><td>The pool can't absorb a trade this size.</td><td><strong>Fix the request.</strong> Reduce <code>sellAmount</code>, or route elsewhere.</td></tr><tr><td><code>invalidBuyAssetAddress</code></td><td><code>NEAR</code></td><td><code>destinationAddress</code> isn't valid for the buy asset's chain. SwapKit does not validate address format at quote time, so this is the provider's check, not ours.</td><td><strong>Fix the request.</strong> Validate against the buy asset's chain.</td></tr><tr><td><code>invalidAddressForChain</code></td><td><code>MAYACHAIN_STREAMING</code></td><td>An address doesn't match the expected format for its chain.</td><td><strong>Fix the request.</strong></td></tr><tr><td><code>swapHalted</code></td><td><code>THORCHAIN_STREAMING</code>,  <code>MAYACHAIN_STREAMING</code>, <code>HARBOR</code></td><td>The protocol has halted trading for that asset or chain. Halts last minutes to hours.</td><td><strong>Route elsewhere.</strong> Don't retry the same provider.</td></tr><tr><td><code>invalidAsset</code>, <code>invalidChain</code>, <code>unsupportedChainId</code>, <code>unsupportedMethod</code></td><td><code>CHAINFLIP</code> (+ streaming), <code>HARBOR</code>, <code>FLASHNET</code>, <code>MAYAN</code></td><td>The provider doesn't support one of the assets or chains, or Mayan returned a quote of a type SwapKit can't price — anything other than its Swift flow.</td><td><strong>Route elsewhere.</strong></td></tr><tr><td><code>noMemoPriceProtection</code></td><td><code>THORCHAIN_STREAMING</code>, <code>MAYACHAIN_STREAMING</code></td><td>The swap memo exceeds the source chain's byte limit once price protection is encoded. Driven by the affiliate name and route shape, not by request parameters.</td><td><strong>Route elsewhere</strong>.</td></tr><tr><td><code>unknownError</code></td><td>most providers</td><td>An unclassified failure, with no actionable detail.</td><td><strong>Retry.</strong> If it persists on one pair, contact support with the <code>quoteId</code>.</td></tr><tr><td><code>quoteError</code></td><td><code>FLASHNET</code></td><td>Flashnet-specific catch-all. Either the chain pair isn't mappable to Flashnet's own chain names, or its quote/estimate call failed. The <code>message</code> is passed through verbatim and is often just <code>"Unknown Error"</code>.</td><td><strong>Retry.</strong></td></tr><tr><td><code>noQuoteResponse</code></td><td><code>NEAR</code>, <code>ONEINCH</code>, <code>CHAINFLIP</code> (+ streaming), <code>GARDEN</code></td><td>The provider call failed and couldn't be classified further.</td><td><strong>Retry.</strong></td></tr><tr><td><code>requestTimeout</code></td><td>all providers</td><td>The provider didn't respond inside SwapKit's quote deadline.</td><td><strong>Retry.</strong></td></tr><tr><td><code>apiRequestFailed</code></td><td><code>THORCHAIN_STREAMING</code>, <code>MAYACHAIN_STREAMING</code>, <code>HARBOR</code>, <code>GARDEN</code></td><td>An upstream provider API call failed.</td><td><strong>Retry.</strong></td></tr></tbody></table>

```json
"providerErrors": [
  {
    "provider": "THORCHAIN_STREAMING",
    "errorCode": "sellAssetAmountTooSmall",
    "message": "Sell asset amount too small",
    "minAmount": "0.0012"
  }
]
```

This covers the codes observed in production between 28 May and 26 August 2026. It isn't exhaustive — new providers and routes can introduce codes not listed here. Treat an unrecognized `errorCode` as **Retry**, and fall back to the other routes in the response.

### What you will and won't see in the response

A provider that was asked and declined reports itself in `providerErrors`, with its own `errorCode` and `message`. A route removed by availability or a ceiling was never asked, so it produces no `providerErrors` entry — the provider is simply absent from `routes`.

So an empty or absent `providerErrors` alongside missing routes is meaningful: it points at [§1](#id-1.-the-provider-name-must-match), [§2](#id-2.-availability-can-be-directional) or [§3](#id-3.-a-route-can-have-a-size-ceiling) rather than at the provider.

`GET /providers/status` reports provider-chain status, not directional availability or ceilings. A surface can show up under `enabledChainsGlobal` and still be closed for sells or bounded by size — the two are separate mechanisms, and `/providers/status` only reflects the first.

### Related

* `/v3/quote` — [Request a swap quote](/swapkit-api/v3-quote-request-a-swap-quote.md) — the full quote error table.
* `/providers` — [Providers, status, and identifiers mapping](/swapkit-api/providers-providers-status-and-identifiers-mapping.md) — what each status field means.
