nautechsystems/nautilus_trader · error · anyhow::Error

cancel algo order failed

Error message

cancel algo order failed

What it means

Canceling an algo (conditional/trigger) order over the OKX REST algo-cancel endpoint failed. This fires both when the HTTP request itself errors and, as a bail, when OKX returns a per-item s_code other than the success code — in which case the message is 'cancel-algo-order-rejected: s_code=..., s_msg=...'. A cancel failure event is emitted to the strategy in the transport-error case.

Source

Thrown at crates/adapters/okx/src/execution.rs:1073

        self.spawn_task("cancel_algo_order", async move {
            let responses = if is_advance {
                http_client.cancel_advance_algo_orders(vec![request]).await
            } else {
                http_client.cancel_algo_orders(vec![request]).await
            };

            match responses {
                Err(e) => {
                    emit_cancel_failure(
                        classify_okx_http_failure(&e),
                        Some((&emitter, clock)),
                        command.client_order_id,
                        command.instrument_id,
                        command.strategy_id,
                        command.venue_order_id,
                    );
                    return Err(anyhow::Error::new(e).context("cancel algo order failed"));
                }
                Ok(resps) => {
                    if let Some((code, msg)) = resps.first().and_then(|r| {
                        r.s_code.as_deref().and_then(|code| {
                            (code != OKX_SUCCESS_CODE)
                                .then_some((code, r.s_msg.as_deref().unwrap_or("unknown")))
                        })
                    }) {
                        let reason =
                            format!("cancel-algo-order-rejected: s_code={code}, s_msg={msg}");
                        let failure = classify_okx_venue_code(code, reason.clone());
                        let is_rejected = matches!(failure, CommandFailure::VenueRejected(_));
                        emit_cancel_failure(
                            failure,
                            Some((&emitter, clock)),
                            command.client_order_id,
                            command.instrument_id,
                            command.strategy_id,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Read the s_code/s_msg in the rejection (or chained HTTP error); if 51400/51401-style 'order not exist' or 'already canceled', treat as no-op and let reconciliation settle state.
  2. Ensure the algo order's venue_order_id (algo_id) is current — reconcile after restart before canceling.
  3. Verify the order type in the cache matches what was submitted (advance algo vs regular algo) so the correct endpoint is used.
  4. Confirm credentials/network if the failure is a transport error rather than a venue rejection.
Defensive patterns

Strategy: validation

Validate before calling

// Ensure the algo order is still cancelable and its algo_id is known
let cancelable = cache.order(&cid)
    .map(|o| matches!(o.order_type(), OrderType::StopLimit | OrderType::StopMarket | OrderType::TrailingStopMarket) && !o.is_closed())
    .unwrap_or(false);
if !cancelable { return; }

Try / catch

// Parse the rejection reason before deciding to retry
if let Err(e) = trader.cancel_order(cid) {
    let msg = format!("{e:#}");
    if msg.contains("cancel-algo-order-rejected") && (msg.contains("51400") || msg.contains("already")) {
        // order gone/triggered: no retry needed
    }
}

Prevention

When it happens

Trigger: cancel_order routed to AlgoHttp; http_client.cancel_algo_orders/cancel_advance_algo_orders returned Err, or the first response item carried s_code != OKX_SUCCESS_CODE (e.g. algo order already triggered/canceled, wrong algo_id, order belongs to another instrument).

Common situations: Canceling a trigger order that already fired into a live order (algo id no longer cancelable); stale venue_order_id after restart; mixing advance (TWAP/OCO-style) and regular algo orders — the adapter picks the endpoint from the cached order type, and a cache miss defaults to the regular endpoint.

Related errors


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