nautechsystems/nautilus_trader · error
Order cancellation failed: {status}
Error message
Order cancellation failed: {status} What it means
After sending a cancel request, Kraken Futures returned result != Success and the cancel_status.status string describes the failure (e.g. 'unknown order', 'already canceled'). The client surfaces that venue-side status verbatim as an anyhow error.
Source
Thrown at crates/adapters/kraken/src/http/futures/client.rs:2326
client_order_id: Option<ClientOrderId>,
venue_order_id: Option<VenueOrderId>,
) -> anyhow::Result<()> {
let _ = self
.get_cached_instrument(&instrument_id.symbol.inner())
.ok_or_else(|| InstrumentLookupError::not_found(instrument_id))?;
let order_id = venue_order_id.as_ref().map(|id| id.to_string());
let cli_ord_id = client_order_id.as_ref().map(truncate_cl_ord_id);
if order_id.is_none() && cli_ord_id.is_none() {
anyhow::bail!("Either client_order_id or venue_order_id must be provided");
}
let response = self.inner.cancel_order(order_id, cli_ord_id).await?;
if response.result != KrakenApiResult::Success {
let status = &response.cancel_status.status;
anyhow::bail!("Order cancellation failed: {status}");
}
Ok(())
}
/// Cancels multiple orders on the Kraken Futures exchange.
///
/// Automatically chunks requests into batches of 50 orders.
///
/// # Parameters
/// - `venue_order_ids` - List of venue order IDs to cancel.
///
/// # Returns
/// The total number of successfully cancelled orders.
pub async fn cancel_orders_batch(
&self,
venue_order_ids: Vec<VenueOrderId>,
) -> anyhow::Result<usize> {View on GitHub (pinned to 18893faf8b)
Solutions
- Read the embedded status in the message: treat 'unknown order'/'notFound' and 'already canceled' as benign idempotent outcomes and handle them non-fatally.
- Confirm the venue_order_id/client_order_id matches a live order via order status before cancelling.
- Check exchange message status / websocket fills to see if the order completed before the cancel arrived.
- Retry only on transient statuses; otherwise stop cancelling and reconcile position state.
Example fix
// before: treat every failure as fatal
client.cancel_order(instrument_id, None, Some(cl_ord_id)).await?;
// after: tolerate already-cancelled/unknown orders
match client.cancel_order(instrument_id, None, Some(cl_ord_id)).await {
Ok(()) => {}
Err(e) if e.to_string().contains("already canceled") || e.to_string().contains("unknown") => {}
Err(e) => return Err(e),
} Defensive patterns
Strategy: try-catch
Validate before calling
// confirm the order is still open via status before cancelling
let status = client.get_order_status(instrument_id, venue_order_id).await?;
if status.is_terminal() { return Ok(()); } Type guard
fn is_benign_cancel_failure(msg: &str) -> bool {
msg.contains("unknown order") || msg.contains("already canceled") || msg.contains("notFound")
} Try / catch
match client.cancel_order(instrument_id, vid, cid).await {
Err(e) if is_benign_cancel_failure(&e.to_string()) => { /* idempotent: already done */ }
Err(e) => return Err(e),
Ok(_) => {}
} Prevention
- Track terminal order states locally and skip cancels for filled/cancelled orders
- Process websocket fill events promptly to keep order state current
- Make cancel handling idempotent — retries are normal in trading loops
When it happens
Trigger: Cancelling an order that was already filled or already cancelled; cancelling with a wrong/expired order id; venue rejection due to auth or rate issues reported in the cancel status; race where the order triggers between submit of cancel and venue processing.
Common situations: Aggressive strategies cancelling stale orders; retries after a network blip cancel twice; a strategy canceling an order that the exchange already matched; clock or reconciliation drift causing stale ids.
Related errors
- Batch cancel failed: {error_msg}
- cancel order rejected: {reason}
- Either client_order_id or venue_order_id must be provided
- {reason}
- cancel algo order failed
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/955c2e521d7e5e1c.
Report an issue: GitHub.