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(¶ms).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
- Match the exact msg string for the common benign case (order already terminated/triggered) and treat it as success instead of an error
- 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)
- Verify the API key, permissions, and environment (testnet vs prod) are identical to those used at submission time
- 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
- Treat 'already terminated / does not exist' style msgs as success in cleanup flows
- Submit and cancel algo orders with the same API key and environment
- Re-query open algo orders before canceling after a restart gap
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
- Cancel all algo orders failed: {}
- Invalid venue order ID: {e}
- Cancel all orders failed: {}
- Instrument not found in cache: {symbol}
- instrument_id is required for historical orders
AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16).
Data as JSON: /api/errors/9ccea5ad0104e119.
Report an issue: GitHub.