nautechsystems/nautilus_trader · error · anyhow::Error
submit order failed
Error message
submit order failed
What it means
OKX execution client's WebSocket-path order submission: submit_regular_order spawns a task that calls place_order_with_domain_types over the WS. If the placement fails, a submit-failure event is emitted for the strategy and the task returns 'submit order failed' wrapping the underlying OKX error. Note submit_order itself returns Ok immediately since the work is spawned.
Source
Thrown at crates/adapters/okx/src/execution.rs:774
px_vol,
outcome,
slippage_pct,
rpi,
rpi_taker_access,
rpi_px_round,
)
.await;
if let Err(e) = result {
emit_submit_failure(
classify_okx_ws_failure(&e),
&emitter,
clock,
strategy_id,
instrument_id,
client_order_id,
);
return Err(anyhow::Error::new(e).context("submit order failed"));
}
Ok(())
});
Ok(())
}
fn submit_order_http(&self, cmd: &SubmitOrder) -> anyhow::Result<()> {
let order = {
let cache = self.core.cache();
cache.try_order_owned(&cmd.client_order_id)?
};
let http_client = self.http_client.clone();
let trade_mode = self.trade_mode_for_order(cmd.instrument_id, &cmd.params);
let emitter = self.emitter.clone();
let clock = self.clock;View on GitHub (pinned to 18893faf8b)
Solutions
- Subscribe to the emitted order-denied/submit-failure events; the underlying OKX error there names the rejection reason.
- Validate price/quantity against the instrument's tick size and lot size before submitting.
- Check account balance/margin and position mode (net vs long/short) matches the order side.
- Ensure the WS connection is healthy (heartbeats, reconnect logic) when using the WS submission path.
Example fix
// before client.submit_order(cmd)?; // returns Ok even if WS place fails later // after client.submit_order(cmd)?; // also handle OrderDenied/submit-failure event for the real OKX error
Defensive patterns
Strategy: try-catch
Validate before calling
// Rust: validate against instrument rules before submit debug_assert_eq!(qty.as_decimal() % instrument.lot_size().as_decimal(), Decimal::ZERO); debug_assert!((price.as_decimal() % instrument.tick_size().as_decimal()).is_zero());
Try / catch
client.submit_order(&cmd)?; // Ok means spawned, not filled
// handle the async failure via actor events:
// on_event(OrderDenied { reason, .. }) => log okx rejection code and adjust order
// on_event(OrderRejected { .. }) => reconcile state Prevention
- Subscribe to order event stream; WS-path failures arrive asynchronously
- Validate tick/lot/min sizes against the instrument before submit
- Match position mode (net vs long/short hedging) in OKX account settings
- Keep WS heartbeats/reconnect healthy on the WS submission path
When it happens
Trigger: submit_order routing to the WS path where the OKX place-order WS request fails — rejected order params (invalid px/sz/tif), post-only would-cross rejection, insufficient balance/margin, rate limit, or WS dropped mid-request.
Common situations: Trading instruments with wrong tick/lot sizes, submitting during OKX WS disconnects, insufficient funds, or FOK orders that cannot fill; failures surface asynchronously in the spawned task, not from submit_order's return.
Related errors
- limit_price is required for order type {order_type:?}
- Invalid `BarSpecification` for channel, was {bar_spec}
- Invalid funding_rate value: {e}
- Expected array payload: {e}
- Unsupported OKX order type: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/a282c9cb8fc4afa4.
Report an issue: GitHub.