nautechsystems/nautilus_trader · error

Cancel algo order failed: code={}, msg={}

Error message

Cancel algo order failed: code={}, msg={}

What it means

Thrown by BinanceFuturesHttpClient::cancel_algo_order when the Binance Algo (conditional order) service returns a response whose code field is not 200. The HTTP layer succeeded (signature, connectivity, rate limits are fine); the algo endpoint itself reported a business failure, and the message embeds the venue's code and msg verbatim. NautilusTrader treats any non-200 code as a failed cancel rather than surfacing a typed per-code error.

Source

Thrown at crates/adapters/binance/src/futures/http/client.rs:2420

    ///
    /// # Errors
    ///
    /// Returns an error if the request fails.
    pub async fn cancel_algo_order(&self, client_order_id: ClientOrderId) -> anyhow::Result<()> {
        let params = BinanceAlgoOrderQueryParams {
            algo_id: None,
            client_algo_id: Some(encode_broker_id(
                &client_order_id,
                BINANCE_NAUTILUS_FUTURES_BROKER_ID,
            )),
            recv_window: None,
        };

        let response = self.inner.cancel_algo_order(&params).await?;
        if response.code.parse::<i32>().unwrap_or(0) == 200 {
            Ok(())
        } else {
            anyhow::bail!(
                "Cancel algo order failed: code={}, msg={}",
                response.code,
                response.msg
            )
        }
    }

    /// Cancels all open orders for a symbol.
    ///
    /// # Errors
    ///
    /// Returns an error if the request fails.
    pub async fn cancel_all_orders(
        &self,
        instrument_id: InstrumentId,
    ) -> anyhow::Result<Vec<VenueOrderId>> {
        let symbol = format_binance_symbol(&instrument_id);

View on GitHub (pinned to a4b06ed870)

Solutions

  1. Match the exact msg string for the common benign case (order already terminated/triggered) and treat it as success instead of an error
  2. Confirm the client_order_id is the same one used when the algo order was submitted through this same client (it gets broker-prefixed before sending)
  3. Verify the API key, permissions, and environment (testnet vs prod) are identical to those used at submission time
  4. Re-query open algo orders before canceling to only cancel IDs that are still live

Example fix

// before
client.cancel_algo_order(client_order_id).await?;

// after
if let Err(e) = client.cancel_algo_order(client_order_id).await {
    let msg = format!("{e}");
    if msg.contains("already") || msg.contains("does not exist") {
        log::info!("algo order already gone: {e}");
    } else {
        return Err(e);
    }
}
Defensive patterns

Strategy: try-catch

Try / catch

// before canceling, only target still-open algo orders
for report in client.request_open_algo_orders().await? {
    if report.client_order_id == target {
        client.cancel_algo_order(target).await?;
    }
}

Prevention

When it happens

Trigger: Canceling via cancel_algo_order(client_order_id) where the client_algo_id (broker-prefixed via encode_broker_id with BINANCE_NAUTILUS_FUTURES_BROKER_ID) does not match any open algo order: order already triggered, expired, or already canceled; submitting the algo order on a different API key/account than the one used to cancel; the order was a regular (non-algo) order submitted through submit_order, not the algo endpoint.

Common situations: Strategy restarts that attempt to clean up algo orders which already fired during downtime; testnet keys paired against production endpoints (or vice versa) so the algo ID is unknown to that environment; racing another cancel path (websocket + HTTP) so the second cancel sees an already-canceled order.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16). Data as JSON: /api/errors/9ccea5ad0104e119. Report an issue: GitHub.