> ## Documentation Index
> Fetch the complete documentation index at: https://v3.docs.derive.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Error Codes

> The JSON-RPC error shape and the full Derive v3 application error catalog.

Every failed request returns a JSON-RPC 2.0 error object, whether the call was made
over WebSocket or HTTP POST. The `error` object always has three fields:

```json theme={null}
{
  "id": "1",
  "jsonrpc": "2.0",
  "error": {
    "code": -32602,
    "message": "Invalid params",
    "data": "expiry: value out of range"
  }
}
```

<ResponseField name="code" type="integer" required>
  The numeric error code. Negative codes are JSON-RPC / transport-level; positive codes are Derive application errors
  (see the catalog below).
</ResponseField>

<ResponseField name="message" type="string" required>
  A short, stable human-readable summary.
</ResponseField>

<ResponseField name="data" type="string | null" required>
  Optional detail (e.g. the offending field or protocol reason). Always present on the wire — it is `null` when there is
  no detail.
</ResponseField>

## JSON-RPC base codes

The standard JSON-RPC 2.0 codes cover malformed or unroutable requests before any
application logic runs.

| Code   | Name               | Message               | When it fires                           |
| ------ | ------------------ | --------------------- | --------------------------------------- |
| −32700 | `parse_error`      | Error parsing message | Request body is not valid JSON          |
| −32603 | `internal_error`   | Internal error        | Any uncaught or internal server failure |
| −32602 | `invalid_params`   | Invalid params        | Params fail validation                  |
| −32601 | `method_not_found` | Method not found      | Unknown RPC method                      |
| −32600 | `invalid_request`  | Invalid Request       | Not a valid JSON-RPC request object     |

<Warning>
  **Internal errors are redacted.** For code **−32603**, the server always returns `message: "Internal error"` and
  `data: null` on the wire — any underlying detail is kept server-side and never leaked to clients. Treat −32603 as
  "retry or contact support," not as a description of what went wrong.
</Warning>

## Transport & session codes

| Code   | Name                            | Message                                                            | When it fires                               |
| ------ | ------------------------------- | ------------------------------------------------------------------ | ------------------------------------------- |
| −32000 | `rate_limit_exceeded`           | Rate limit exceeded                                                | Per-wallet or per-instrument limit hit      |
| −32000 | `custom_rate_limit_error`       | *(caller-supplied)*                                                | A method-specific rate-limit rejection      |
| −32100 | `concurrent_ws_client_exceeded` | Number of concurrent websocket clients limit exceeded              | Too many concurrent WebSocket connections   |
| 401    | `unauthorized`                  | Unauthorized                                                       | Missing or invalid authentication           |
| 403    | `forbidden`                     | Forbidden                                                          | Authenticated but not permitted             |
| 403    | `restricted_region`             | You are in a restricted region that violates our terms of service. | Request originates from a geoblocked region |

See [Rate limits](/rate-limits) for how the two-tier limiter works and how to read
your live limits, and [Authentication](/authentication/session-login) for the session-login and
action-signing layers behind the 401/403 and 14xxx codes.

## Application error catalog

Application errors use positive codes grouped by numeric range. Codes are stable;
gaps within a range are reserved.

<Note>
  Internal **8xxx** codes (e.g. counterparty/feed diagnostics) are intentionally omitted from this reference — they are
  server-side signals, not client-actionable, and are excluded from public docs.
</Note>

### 9xxx — Confirmation timeouts

The order was accepted but a downstream confirmation did not arrive in time. Query
order state before resubmitting.

| Code | Name                          | Message                     | When it fires                                         |
| ---- | ----------------------------- | --------------------------- | ----------------------------------------------------- |
| 9000 | `order_confirmation_timeout`  | Order confirmation timeout  | Order confirmation timed out                          |
| 9001 | `engine_confirmation_timeout` | Engine confirmation timeout | Matching-engine confirmation timed out; order dropped |

### 10xxx — Accounts, transfers & margin

Rejections from account, session-key, and subaccount-level constraints before an
order reaches the book.

| Code  | Name                                                 | Message                                                                                        | When it fires                                  |
| ----- | ---------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------- |
| 10001 | `asset_not_erc20`                                    | Asset is not an ERC20 token                                                                    | Deposit/withdraw/transfer of a non-ERC20 asset |
| 10003 | `same_account_transfer`                              | Sender and recipient subaccount IDs are the same                                               | Self-transfer                                  |
| 10004 | `multiple_currencies_not_supported`                  | Multiple currencies not supported                                                              | Mixed-currency request rejected                |
| 10006 | `max_session_keys_per_wallet`                        | Maximum number of session keys per wallet reached                                              | Session-key cap reached                        |
| 10007 | `max_assets_per_subaccount_exceeded`                 | Maximum number of assets per subaccount reached                                                | Per-subaccount asset cap reached               |
| 10010 | `pmrm_only_supports_quote_asset`                     | PMRM only supports USDC asset collateral. Cannot trade spot markets.                           | PMRM subaccount tried to trade spot            |
| 10015 | `pm2_only_support_single_currency_options_and_perps` | PortfolioMargin2 supports multiple collaterals but only options and perps of the same currency | PM2 cross-currency options/perps               |
| 10016 | `pm2_does_not_support_this_collateral`               | PortfolioMargin2 does not support this collateral                                              | PM2 unsupported collateral                     |

### 11000–11035 — Orders & matching

Order-lifecycle rejections from the matching engine.

| Code  | Name                                    | Message                                                         | When it fires                                              |
| ----- | --------------------------------------- | --------------------------------------------------------------- | ---------------------------------------------------------- |
| 11000 | `insufficient_funds`                    | Insufficient funds                                              | Insufficient margin/funds for the order                    |
| 11006 | `order_does_not_exist`                  | Does not exist                                                  | Cancel/query of an unknown order                           |
| 11007 | `self_crossing_disallowed`              | Self-crossing disallowed                                        | Order would cross your own resting order                   |
| 11008 | `post_only_reject`                      | Post only order cannot cross the market                         | Post-only order would match immediately                    |
| 11009 | `zero_liquidity_for_taker_order`        | Zero liquidity for market or IOC/FOK order                      | No liquidity within the limit price                        |
| 11011 | `order_invalid_signature_expiry`        | Invalid signature expiry                                        | Expiry outside the allowed validity window                 |
| 11012 | `invalid_amount`                        | Invalid amount                                                  | Order amount invalid                                       |
| 11013 | `order_invalid_limit_price`             | Invalid limit price                                             | Limit price invalid                                        |
| 11014 | `fok_not_filled`                        | Fill-or-kill not filled                                         | FOK order could not be fully filled                        |
| 11015 | `mmp_frozen`                            | MMP frozen                                                      | Market-maker protection frozen for the subaccount/currency |
| 11017 | `non_unique_nonce`                      | Non unique nonce                                                | Nonce already used                                         |
| 11018 | `order_invalid_nonce`                   | Invalid nonce date                                              | Leading nonce digits are not a valid UTC-second timestamp  |
| 11019 | `too_many_orders`                       | Too many orders                                                 | Open-order cap per subaccount reached                      |
| 11020 | `negative_erc20_balance`                | Negative ERC20 balance                                          | Wrapped ERC20 balance would go negative                    |
| 11021 | `instrument_not_live`                   | Instrument is not live                                          | Instrument deactivated or expired                          |
| 11022 | `reject_timestamp_exceeded`             | Reject timestamp exceeded                                       | Order arrived after its `reject_timestamp`                 |
| 11023 | `max_fee_too_low`                       | Max fee order param is too low                                  | `max_fee` below the required minimum                       |
| 11024 | `reduce_only_not_supported`             | Reduce only not supported with this time in force               | Reduce-only requires market/IOC/FOK                        |
| 11025 | `reduce_only_reject`                    | Reduce only reject                                              | Reduce-only order would increase the position              |
| 11027 | `undergoing_liquidation`                | Subaccount undergoing liquidation                               | Subaccount is being liquidated                             |
| 11028 | `replace_order_filled_amount_mismatch`  | Replaced order filled amount does not match expected state.     | Replace saw an unexpected filled amount                    |
| 11029 | `oi_cap_exceeded`                       | Trade or transfer rejected: open interest cap would be exceeded | Open-interest cap for the manager exceeded                 |
| 11030 | `fee_consumes_amount`                   | Fee consumes entire amount                                      | Fee is ≥ the transfer/withdraw amount                      |
| 11031 | `withdrawal_rounds_to_zero`             | Withdrawal rounds to zero                                       | Net withdrawal rounds to zero in native decimals           |
| 11032 | `transfer_below_min`                    | Transfer below minimum                                          | New-subaccount funding below the minimum                   |
| 11033 | `transfer_not_whitelisted`              | Transfer recipient not whitelisted                              | Recipient not on the sender's whitelist                    |
| 11034 | `withdrawals_blocked_insolvent_auction` | Withdrawals blocked by insolvent auction                        | Withdrawals paused during an insolvent auction             |
| 11035 | `non_increasing_nonce`                  | Non increasing nonce                                            | Signed-action nonce is not strictly increasing             |

### 11050–11055 — Trigger orders

Stop / trigger-order specific rejections.

| Code  | Name                                              | Message                                                                                   | When it fires                                  |
| ----- | ------------------------------------------------- | ----------------------------------------------------------------------------------------- | ---------------------------------------------- |
| 11050 | `trigger_order_already_cancelled_or_expired`      | Trigger order was cancelled between the time worker sent order and engine processed order | Trigger cancelled before it could be processed |
| 11051 | `invalid_trigger_price`                           | Trigger price must be higher than current price for stop orders and vice versa            | Trigger price on the wrong side                |
| 11052 | `too_many_trigger_orders`                         | Trigger order limit exceeded (separate limit from regular orders)                         | Trigger-order cap reached                      |
| 11053 | `trigger_price_type_not_supported`                | Index and last-trade trigger price types not supported yet                                | Only mark-price triggers are supported         |
| 11054 | `cannot_replace_or_be_replaced_by_trigger_orders` | Trigger orders cannot replace or be replaced                                              | Replace involving a trigger order              |
| 11055 | `unfillable_market_trigger_order`                 | Market order limit\_price is unfillable at the given trigger price                        | Market trigger would not be crossable          |

<Info>
  A parallel **11150–11155** code range for trigger-order rejects appears in the reject-message mapping and may surface
  for some persisted trigger rejections. Handle trigger rejects by `name`/`message` rather than hard-coding `11050` vs
  `11150`.
</Info>

### 11100–11113 — RFQs & quotes

Request-for-quote and quote-matching rejections.

| Code  | Name                                     | Message                                         | When it fires                                     |
| ----- | ---------------------------------------- | ----------------------------------------------- | ------------------------------------------------- |
| 11100 | `leg_instruments_not_unique`             | Leg instruments are not unique                  | Repeated instrument across RFQ/quote legs         |
| 11101 | `rfq_not_found`                          | RFQ not found                                   | RFQ query/cancel matched nothing                  |
| 11102 | `quote_not_found`                        | Quote not found                                 | Quote query/cancel matched nothing                |
| 11103 | `quote_leg_mismatch_vs_rfq`              | Quote leg does not match RFQ leg                | Quote legs differ from RFQ legs                   |
| 11104 | `quote_rfq_not_open`                     | Requested quote or RFQ is not open              | RFQ expired, filled, or cancelled                 |
| 11105 | `quote_rfq_id_mismatch`                  | Quote references a different RFQ than requested | Quote's RFQ id differs from the one provided      |
| 11106 | `rfq_invalid_counterparty`               | Invalid RFQ counterparty                        | Counterparty unauthorized or nonexistent          |
| 11107 | `quote_maker_cost_too_high`              | Quote maker total cost too high                 | Maker cost exceeded the price bandwidth           |
| 11108 | `rfq_partial_fill_pct_too_high`          | RFQ partial fill percentage too high            | Fill exceeds the requested total size             |
| 11109 | `rfq_filled_direction_cannot_be_changed` | RFQ filled direction cannot be changed          | A later fill would flip the direction             |
| 11110 | `quote_taker_cost_too_high`              | Quote taker total cost too high                 | Taker cost exceeded the orderbook execution price |
| 11111 | `rfq_disabled_for_account`               | RFQ functionality is disabled for this account  | RFQ disabled for the account                      |
| 11112 | `rfq_too_many_legs`                      | RFQ has too many legs                           | Leg count over the maximum                        |
| 11113 | `rfq_too_many_counterparties`            | RFQ has too many counterparties                 | Counterparty count over the maximum               |

### 12xxx — Market data

| Code  | Name                   | Message              | When it fires      |
| ----- | ---------------------- | -------------------- | ------------------ |
| 12001 | `instrument_not_found` | Instrument not found | Unknown instrument |
| 12002 | `currency_not_found`   | Currency not found   | Unknown currency   |
| 12003 | `asset_not_found`      | Asset not found      | Unknown asset      |

### 13000 — Subscriptions

| Code  | Name               | Message          | When it fires                             |
| ----- | ------------------ | ---------------- | ----------------------------------------- |
| 13000 | `invalid_channels` | Invalid channels | Unknown or malformed subscription channel |

### 14xxx — Authentication & authorization

Session-login, signature, and session-key scope failures. See
[Authentication](/authentication/session-login) for the underlying scheme.

| Code  | Name                               | Message                                                                          | When it fires                                            |
| ----- | ---------------------------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------- |
| 14000 | `account_not_found`                | Account not found                                                                | Account does not exist                                   |
| 14001 | `subaccount_not_found`             | Subaccount not found                                                             | Subaccount not owned by a registered wallet              |
| 14013 | `string_is_not_ethereum_address`   | String is not a valid ethereum address                                           | Malformed address                                        |
| 14014 | `invalid_signature`                | Signature invalid for message or transaction                                     | Recovered signer does not match the expected signer      |
| 14020 | `auth_header_mismatch`             | The X-DeriveWallet header does not match the requested subaccount\_id or wallet  | Auth header subject mismatch                             |
| 14021 | `ip_not_whitelisted`               | IP not whitelisted                                                               | Request IP not on the whitelist                          |
| 14023 | `invalid_signer`                   | Signer in on-chain related request is not wallet owner or registered session key | Signer is neither the owner nor a registered session key |
| 14026 | `session_key_not_found`            | Session key not found                                                            | Unknown session key                                      |
| 14027 | `unauthorized_as_rfq_maker`        | Unauthorized as RFQ maker                                                        | Account is not an RFQ maker                              |
| 14028 | `cross_currency_rfq_not_supported` | Cross currency RFQ not supported                                                 | RFQ legs span multiple currencies                        |
| 14030 | `session_key_expired`              | Session key expired                                                              | Session key is past its expiry                           |
| 14031 | `unauthorized_key_scope`           | Unauthorized Key Scope                                                           | Session-key scope insufficient for the action            |
| 14033 | `account_not_atomic_whitelisted`   | Account not whitelisted for atomic orders                                        | Atomic order from a non-whitelisted account              |
| 14035 | `session_key_already_registered`   | Session key already registered                                                   | Session key already belongs to another wallet            |

### 16xxx — Compliance

| Code  | Name               | Message                                               | When it fires                        |
| ----- | ------------------ | ----------------------------------------------------- | ------------------------------------ |
| 16001 | `account_disabled` | Account is disabled due to compliance violations      | Account disabled by compliance       |
| 16002 | `ofac_blocked`     | Account is blocked due to OFAC compliance violations. | Account blocked under OFAC screening |

### 17xxx — Risk universes

| Code  | Name                    | Message               | When it fires                                   |
| ----- | ----------------------- | --------------------- | ----------------------------------------------- |
| 17000 | `cross_universe_trade`  | Cross universe trade  | Participants belong to different risk universes |
| 17001 | `unknown_risk_universe` | Unknown risk universe | Referenced risk universe does not exist         |

### 18xxx — Vaults

| Code  | Name                                               | Message                                           | When it fires                                       |
| ----- | -------------------------------------------------- | ------------------------------------------------- | --------------------------------------------------- |
| 18007 | `vault_not_found`                                  | Vault not found                                   | Subaccount is not a vault                           |
| 18008 | `exceeded_max_user_requests`                       | Exceeded maximum number of pending vault requests | Too many pending deposit/withdraw requests          |
| 18009 | `max_shareholder_vaults_reached`                   | Exceeded maximum number of shareholder vaults     | Shareholder-vault cap reached                       |
| 18010 | `vault_closed`                                     | Vault is closed                                   | Vault has been fully withdrawn/closed               |
| 18011 | `vault_cooldown_active`                            | Vault withdrawal cooldown active                  | Deposit→withdraw cooldown not elapsed               |
| 18012 | `vault_creation_deposit_below_min`                 | Vault creation deposit below minimum              | Curator's initial deposit below the minimum         |
| 18013 | `vault_curator_stake_below_min`                    | Curator stake below minimum                       | Withdrawal would drop curator stake below the floor |
| 18014 | `vault_slippage_exceeded`                          | Vault quote outside slippage band                 | Share price outside the accepted band               |
| 18015 | `vault_amount_below_min`                           | Vault amount below minimum                        | Deposit/withdraw below the per-asset minimum        |
| 18016 | `vault_signature_expiry_too_long`                  | Vault signature expiry too far out                | Expiry more than 30 days out                        |
| 18017 | `vault_benchmark_price_unavailable`                | Vault HWM benchmark price unavailable             | High-water-mark benchmark has no feed               |
| 18018 | `vault_initial_share_price_too_far_from_benchmark` | Vault initial share price too far from benchmark  | Initial price too far from the benchmark            |
| 18019 | `vault_deposit_exceeds_margin`                     | Insufficient margin for vault deposit             | Source subaccount cannot back the deposit           |

### 20000 — Protocol

| Code  | Name              | Message                     | When it fires                                                      |
| ----- | ----------------- | --------------------------- | ------------------------------------------------------------------ |
| 20000 | `protocol_reject` | Protocol rejected operation | The protocol layer rejected the operation; the reason is in `data` |

## Handling errors

<Tip>
  Branch on `code` for programmatic handling and surface `message` (and `data` when present) to users. Never parse
  `message` text — it is stable but treat `code` as the contract. For −32603, retry with backoff rather than inspecting
  the (redacted) body.
</Tip>


## Related topics

- [List all referral codes](/api-reference/referrals/list-all-referral-codes.md)
- [Rate Limits](/rate-limits.md)
- [Subscriptions](/subscriptions.md)
