nautechsystems/nautilus_trader · error · anyhow::Error

WS cancel order failed

Error message

WS cancel order failed: {e}

What it means

Thrown when cancelling a Binance Spot order over the WebSocket API fails. Like the submit path, the pending request is removed and a warning is logged noting the cancel result will be resolved by reconciliation, then the error propagates to `cancel_order`.

Solutions

  1. Read the logged inner error for the Binance reject reason (e.g. -2011 Unknown order sent) and verify the client_order_id/order state
  2. Rely on reconciliation/order status events to learn the order's final state rather than immediately re-cancelling
  3. Check connectivity to the WS API endpoint and credentials
  4. Retry the cancel only after confirming the order is still open
Defensive patterns

Strategy: try-catch

Try / catch

if let Err(e) = client.cancel_order(&command).await {
    log::warn!("cancel failed: {e}; order state will arrive via reconciliation");
}

Prevention

When it happens

Trigger: `cancel_order_internal` sends a cancel-order WS API request and the response/await fails — Binance rejects the cancel (unknown order, already filled, wrong orig_client_order_id), signature/auth error, or the WS connection failed before a response arrived.

Common situations: Cancelling an order that was already filled or expired; using a client_order_id that Binance does not recognize; network drop while the cancel request is in flight; strategy cancelling stale orders after a reconnect.

Understand the failure class

Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.

Related errors


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

Appendix: source

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

                request_id.clone(),
                PendingRequest {
                    client_order_id: command.client_order_id,
                    venue_order_id: command.venue_order_id,
                    operation: PendingOperation::Cancel,
                },
            );

            self.spawn_task("cancel_order_ws", async move {
                if let Err(e) = ws_client
                    .cancel_order_with_id(request_id.clone(), params)
                    .await
                {
                    dispatch_state.pending_requests.remove(&request_id);
                    log::warn!(
                        "WS cancel request failed for {}, awaiting reconciliation: {e}",
                        command.client_order_id
                    );
                    anyhow::bail!("WS cancel order failed: {e}");
                }
                Ok(())
            });
        } else {
            let http_client = self.http_client.clone();
            let dispatch_state = self.dispatch_state.clone();
            log::debug!("WS trading not active, falling back to HTTP for cancel_order");

            self.spawn_task("cancel_order_http", async move {
                let result = http_client
                    .cancel_order(
                        command.instrument_id,
                        command.venue_order_id,
                        Some(command.client_order_id),
                    )
                    .await;

                match result {

View on GitHub (pinned to 18893faf8b)