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.
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.
Present and enabled, no amount works, the reverse direction works
directional availability (§2)
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.
sellAssetAmountTooSmall
THORCHAIN_STREAMING, MAYACHAIN_STREAMING, CHAINFLIP (+ streaming), NEAR, HARBOR, FLASHNET
Below the provider's minimum.
Fix the request. Read minAmount and retry at or above it.
insufficientLiquidity
CHAINFLIP (+ streaming), NEAR, HARBOR, GARDEN
The pool can't absorb a trade this size.
Fix the request. Reduce sellAmount, or route elsewhere.
invalidBuyAssetAddress
NEAR
destinationAddress 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.
Fix the request. Validate against the buy asset's chain.
invalidAddressForChain
MAYACHAIN_STREAMING
An address doesn't match the expected format for its chain.
Fix the request.
swapHalted
THORCHAIN_STREAMING, MAYACHAIN_STREAMING, HARBOR
The protocol has halted trading for that asset or chain. Halts last minutes to hours.
Route elsewhere. Don't retry the same provider.
invalidAsset, invalidChain, unsupportedChainId, unsupportedMethod
CHAINFLIP (+ streaming), HARBOR, FLASHNET, MAYAN
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.
Route elsewhere.
noMemoPriceProtection
THORCHAIN_STREAMING, MAYACHAIN_STREAMING
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.
Route elsewhere.
unknownError
most providers
An unclassified failure, with no actionable detail.
Retry. If it persists on one pair, contact support with the quoteId.
quoteError
FLASHNET
Flashnet-specific catch-all. Either the chain pair isn't mappable to Flashnet's own chain names, or its quote/estimate call failed. The message is passed through verbatim and is often just "Unknown Error".
Retry.
noQuoteResponse
NEAR, ONEINCH, CHAINFLIP (+ streaming), GARDEN
The provider call failed and couldn't be classified further.
Retry.
requestTimeout
all providers
The provider didn't respond inside SwapKit's quote deadline.
Retry.
apiRequestFailed
THORCHAIN_STREAMING, MAYACHAIN_STREAMING, HARBOR, GARDEN
An upstream provider API call failed.
Retry.
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, §2 or §3 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 — the full quote error table./providers— Providers, status, and identifiers mapping — what each status field means.
Last updated

