nautechsystems/nautilus_trader · error

cancel-all response contains an order for a different instru

Error message

cancel-all response contains an order for a different instrument

What it means

Binance's cancel-all-orders (openOrders delete) response returned a prepared cancel whose instrument_id does not match the instrument the cancel command targeted. The adapter validates the response before emitting cancel events so that order state is never mutated for the wrong instrument. This is a safety invariant violation on the exchange response, not a client request failure.

Source

Thrown at crates/adapters/binance/src/spot/execution.rs:1969

        let lifecycle_lock = self.lifecycle_lock.clone();

        // Build strategy lookup from cache before spawning (cache is not Send)
        let strategy_lookup: AHashMap<ClientOrderId, StrategyId> = {
            let cache = self.core.cache();
            cache
                .orders_open(None, Some(&cmd.instrument_id), None, None, None)
                .into_iter()
                .map(|order| (order.client_order_id(), order.strategy_id()))
                .collect()
        };

        let command = cmd;
        self.spawn_task("cancel_all_orders_http", async move {
            let responses = http_client
                .cancel_all_order_responses(command.instrument_id)
                .await?;
            let canceled_orders = prepare_cancel_all_orders(responses)?;
            anyhow::ensure!(
                canceled_orders
                    .iter()
                    .all(|order| order.instrument_id == command.instrument_id),
                "cancel-all response contains an order for a different instrument",
            );
            let _lifecycle_guard = lifecycle_lock.lock();

            for canceled_order in canceled_orders {
                let client_order_id = canceled_order.client_order_id;
                if canceled_order.order_list {
                    dispatch_order_list_canceled(
                        &canceled_order,
                        &event_emitter,
                        account_id,
                        &dispatch_state,
                        clock.get_time_ns(),
                    );
                    continue;

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Log the raw cancel_all_order_responses payload and the offending order's instrument_id to identify which symbol mismatched
  2. Verify the InstrumentId passed to cancel_all_orders matches the Binance symbol exactly (no stale instrument definition)
  3. Retry cancel_all_orders once the mismatched response subsides; if it persists, report the exchange response inconsistency
  4. Compare the instrument definition (crates/adapters/binance instrument parsing) against the returned symbol to rule out mapping drift

Example fix

// before
canceled_orders.iter().all(|order| order.instrument_id == command.instrument_id)
// after
// same check, but log the mismatch first to diagnose:
for order in &canceled_orders {
    if order.instrument_id != command.instrument_id {
        tracing::error!("cancel-all mismatch: got {} expected {}", order.instrument_id, command.instrument_id);
    }
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Rust caller: verify command targets a live instrument before cancel
assert_eq!(command.instrument_id, expected_instrument_id);

Try / catch

match cancel_all_orders(command.instrument_id).await {
    Ok(_) => {},
    Err(e) if e.to_string().contains("different instrument") => {
        tracing::warn!("exchange returned foreign symbol in cancel-all; ignoring");
    },
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling cancel_all_orders for instrument A while the HTTP cancel_all_order_responses call returns order reports that resolve to instrument B — e.g. the exchange response's symbol maps to a different InstrumentId, or the response contains stale/foreign symbols such as orders in a different quote asset.

Common situations: Exchange responses mixing symbols during rapid cancel-all on a multi-symbol account; symbol-to-InstrumentId mapping drift after instrument redefinition; a buggy or intercepted HTTP response.

Related errors


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