nautechsystems/nautilus_trader · error

order {} reports status {:?}, expected Canceled

Error message

order {} reports status {:?}, expected Canceled

What it means

prepare_cancel_order requires every cancel-all/cancel-list child response to report SbeOrderStatus::Canceled. Any other status (e.g. NEW, PENDING_CANCEL, REJECTED, EXPIRED) fails this check because the adapter only treats an explicitly Canceled confirmation as a successful cancel.

Source

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

) -> anyhow::Result<()> {
    anyhow::ensure!(
        response.order_id >= 0
            && !response.symbol.is_empty()
            && !response.orig_client_order_id.is_empty(),
        "cancel-all response has an invalid order ID, symbol, or original client order ID",
    );
    anyhow::ensure!(
        response.status == SbeOrderStatus::Canceled,
        "order {} reports status {:?}, expected Canceled",
        response.order_id,
        response.status,
    );
    let client_order_id = decode_client_order_id(
        &response.orig_client_order_id,
        BINANCE_NAUTILUS_SPOT_BROKER_ID,
    )?;
    let instrument_id = InstrumentId::new(response.symbol.as_str().into(), *BINANCE_VENUE);
    anyhow::ensure!(
        order_ids.insert((instrument_id, response.order_id)),
        "cancel-all response contains duplicate order ID {} for {}",
        response.order_id,
        instrument_id,
    );
    anyhow::ensure!(
        client_order_ids.insert(client_order_id),
        "cancel-all response contains duplicate client order ID {client_order_id}",
    );
    prepared.push(PreparedCancelOrder {
        venue_order_id: VenueOrderId::new(response.order_id.to_string()),
        transaction_time: response.transact_time,
        client_order_id,
        instrument_id,
        order_list,
    });
    Ok(())
}

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Check order status before canceling; skip already-terminal orders
  2. Treat the error as a race condition and retry only orders still open
  3. Use client.supplied_order_status / order status reports to reconcile state
  4. Avoid duplicate cancels for the same order
Defensive patterns

Strategy: try-catch

Try / catch

match result { Err(e) if e.to_string().contains("expected Canceled") => { /* order likely already filled/canceled; query status and continue */ } Err(e) => return Err(e), Ok(_) => continue }

Prevention

When it happens

Trigger: Calling cancel_all_orders / cancel_order_list when Binance reports a non-Canceled status for one of the child orders — e.g. the order was already filled, already canceled, or the cancel is still pending at the venue.

Common situations: Race conditions where the order fills just as cancel-all is issued; repeated cancels of the same order; canceling orders that expired via time-in-force (FOK/GTD).

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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