nautechsystems/nautilus_trader · error · anyhow::Error
cancel order failed
Error message
cancel order failed
What it means
The Polymarket execution client's cancel_order_command issues a cancel over HTTP/WebSocket and, when the cancel request itself errors, wraps it with "cancel order failed". If the outcome is merely unknown, it logs and defers to reconciliation; this error means the cancel API call definitively failed.
Source
Thrown at crates/adapters/polymarket/src/execution/cancellations.rs:271
CommandFailure::VenueRejected(reason)
| CommandFailure::NotSent(reason) => {
let ts_now = clock.get_time_ns();
emitter.emit_order_cancel_rejected(
&order_clone,
Some(venue_order_id),
&reason,
ts_now,
);
}
CommandFailure::Ambiguous(reason) => {
log::warn!(
"Cancel outcome unknown for {} ({}), awaiting reconciliation: {reason}",
order_clone.client_order_id(),
venue_order_id,
);
}
}
return Err(anyhow::Error::new(e).context("cancel order failed"));
}
}
Ok(())
});
}
pub(super) fn cancel_all_orders_command(&self, cmd: &CancelAllOrders) -> anyhow::Result<()> {
let cache = self.core.cache();
let side = cmd.order_side;
let asset_id = if side.is_none() {
let instrument = cache.instrument(&cmd.instrument_id).ok_or_else(|| {
anyhow::anyhow!(
"Cannot cancel all orders: instrument not found in cache for {}",
cmd.instrument_id
)
})?;
Some(instrument.raw_symbol().to_string())
} else {View on GitHub (pinned to 18893faf8b)
Solutions
- Check the underlying anyhow chain / logs for the CLOB error code (already-canceled vs auth vs network).
- If order already filled/canceled, treat as success and skip re-canceling.
- Verify Polymarket API credentials and that the signer nonce is current; re-derive API keys if needed.
- Retry the cancel with fresh order state after reconciliation, not before.
- Confirm the venue_order_id/client_order_id being canceled is still live.
Example fix
// before
let _ = client.cancel_order(&instrument_id, &client_order_id);
// after
if let Err(e) = client.cancel_order(&instrument_id, &client_order_id) {
if !order_is_terminal(order.status()) {
return Err(e);
} // already filled/canceled: safe to ignore
} Defensive patterns
Strategy: try-catch
Validate before calling
// check the order is still live before canceling
if order.status() != OrderStatus::Accepted { return Ok(()); } Try / catch
match client.cancel_order(&instrument_id, &client_order_id) {
Ok(()) => {}
Err(e) if order_is_terminal(order.status()) => { /* raced with fill: safe */ }
Err(e) => return Err(e),
} Prevention
- Check local order status before issuing cancels to avoid fill races
- Keep Polymarket API credentials and nonces synchronized
- Handle 'already canceled/matched' responses as success
- Reconcile order state after any cancel failure before retrying
When it happens
Trigger: Calling cancel_order for an order on Polymarket when the CLOB API rejects the request: order already matched/canceled, invalid order id, authentication failure (bad API key/nonce), or network/HTTP error from the CLOB endpoint.
Common situations: Racing a fill so the order is gone and the cancel 4xx's; expired or out-of-sync Polymarket API credentials (nonce mismatch); a stale venue_order_id after a session restart; CLOB service outage.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- failed to cancel all orders
- failed to batch cancel orders
- Order cancellation failed: {status}
- Failed to probe market closure for {failed_chunks} of {total
- All {total} event slug requests failed
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/4cb22f0081316b22.
Report an issue: GitHub.