nautechsystems/nautilus_trader · error

Query order state failed: {e}

Error message

Query order state failed: {e}

What it means

Raised in `DeribitExecutionClient::query_order` when the actual `get_order_state` RPC to Deribit fails after the venue_order_id was successfully extracted. The adapter wraps the underlying ws-client error with `anyhow!("Query order state failed: {e}")`, so the root cause (rejected request, unknown order id, timeout, transport failure) is inside `{e}`.

Source

Thrown at crates/adapters/deribit/src/execution.rs:818

        let trader_id = cmd.trader_id;
        let strategy_id = cmd.strategy_id;
        let instrument_id = cmd.instrument_id;

        log::debug!("Querying order state: order_id={order_id}, client_order_id={client_order_id}");

        // Spawn async task to query order state via WebSocket
        // Response will be dispatched through the WebSocket stream handler as OrderStatusReport
        self.spawn_task("query_order", async move {
            ws_client
                .query_order(
                    &order_id,
                    client_order_id,
                    trader_id,
                    strategy_id,
                    instrument_id,
                )
                .await
                .map_err(|e| anyhow::anyhow!("Query order state failed: {e}"))?;
            Ok(())
        });

        Ok(())
    }

    fn submit_order(&self, cmd: SubmitOrder) -> anyhow::Result<()> {
        let order = self.core.cache().try_order_owned(&cmd.client_order_id)?;
        self.submit_single_order(&order, "submit_order");
        Ok(())
    }

    fn submit_order_list(&self, cmd: SubmitOrderList) -> anyhow::Result<()> {
        if cmd.order_list.client_order_ids.is_empty() {
            log::debug!("submit_order_list called with empty order list");
            return Ok(());
        }

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Inspect the wrapped `{e}` to distinguish auth vs unknown-order vs transport causes.
  2. Verify the `venue_order_id` exists on the connected environment and within Deribit's order-state lookup window.
  3. Reconnect/re-authenticate if the ws session dropped, then retry the query.
  4. Check API key validity and permissions for `private/get_order_state`.
  5. Add retry-with-backoff around query_order for transient transport errors.

Example fix

// before
client.query_order(cmd).await?; // panics pipeline on transient ws error

// after
match client.query_order(cmd).await {
    Ok(()) => {},
    Err(e) if is_retryable(&e) => retry_with_backoff(3, || client.query_order(cmd.clone())).await?,
    Err(e) => return Err(e),
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Before querying, confirm the order id is from the same environment and recent enough
assert_eq!(order.venue.as_str(), "DERIBIT");
assert!(order.is_recent(DERIBIT_ORDER_STATE_RETENTION));

Try / catch

// Rust
match client.query_order(cmd).await {
    Ok(()) => {}
    Err(e) if format!("{e:#}").contains("Query order state failed") => {
        // check inner error: re-auth / reconnect on transport errors, skip on unknown-order
    }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: Calling `query_order` with a valid `venue_order_id` where the subsequent Deribit `private/get_order_state` call returns Err — unknown/cancelled-long-ago order id purged by the venue, session/auth failure, network drop or ws reconnect in progress, or RPC timeout.

Common situations: Querying orders older than Deribit's `get_order_state` retention; querying on testnet with a mainnet order id (or vice versa); transient disconnects; expired API credentials; malformed instrument context causing the wrong request.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/c4829db136fcc1de. Report an issue: GitHub.