nautechsystems/nautilus_trader · error · anyhow::Error
Failed to send order denied event: {e}
Error message
Failed to send order denied event: {e} What it means
This error wraps a failure to deliver an OrderDenied event over the exec_sender channel while rejecting an order whose `post_only` flag is not supported by Interactive Brokers. It is a secondary error: the adapter tries to report the denial to the execution engine, and if the event channel itself is closed/saturated, the send failure becomes this anyhow error. The original denial reason (post_only unsupported) is then raised with anyhow::bail!.
Source
Thrown at crates/adapters/interactive_brokers/src/execution/core_orders.rs:46
clock: &'static AtomicTime,
account_id: AccountId,
order_submit_lock: &Arc<tokio::sync::Mutex<()>>,
) -> anyhow::Result<()> {
if cmd.order_init.post_only {
let ts_event = clock.get_time_ns();
let event = OrderDenied::new(
cmd.order_init.trader_id,
cmd.strategy_id,
cmd.instrument_id,
cmd.order_init.client_order_id,
Ustr::from("`post_only` not supported by Interactive Brokers"),
UUID4::new(),
ts_event,
ts_event,
);
exec_sender
.send(ExecutionEvent::Order(OrderEventAny::Denied(event)))
.map_err(|e| anyhow::anyhow!("Failed to send order denied event: {e}"))?;
anyhow::bail!("`post_only` not supported by Interactive Brokers");
}
let is_inverse = instrument_provider
.find(&cmd.instrument_id)
.map(|instrument| instrument.is_inverse())
.unwrap_or(false);
if cmd.order_init.quote_quantity && !is_inverse {
let ts_event = clock.get_time_ns();
let event = OrderDenied::new(
cmd.order_init.trader_id,
cmd.strategy_id,
cmd.instrument_id,
cmd.order_init.client_order_id,
Ustr::from("UNSUPPORTED_QUOTE_QUANTITY"),
UUID4::new(),
ts_event,View on GitHub (pinned to 18893faf8b)
Solutions
- Set post_only = false on the order (or omit it); emulate maker-only behavior with an IB limit order and LEE/MKT TIF instead.
- Use an order type supported by IB (limit orders only for post-only-like behavior).
- Check that the adapter's execution event channel is alive; reconnect the execution client if the send itself failed.
- Inspect the chained error message from the send (the {e} payload) to distinguish channel failure from the intended denial.
Example fix
// before let cmd = SubmitOrder::new(..., post_only: true, ...); // after let cmd = SubmitOrder::new(..., post_only: false, ...); // IB does not support post_only
Defensive patterns
Strategy: validation
Validate before calling
if order_init.post_only {
return Err(anyhow::anyhow!("IB adapter does not support post_only orders"));
} Prevention
- Never set post_only for Interactive Brokers orders; use limit orders with appropriate TIF.
- Check adapter capability docs before reusing order configs across venues.
- Validate order flags against the target venue in strategy pre-trade checks.
When it happens
Trigger: Submitting an order via handle_submit_order_async with order_init.post_only set to true while using the Interactive Brokers adapter; the send itself fails only when the execution event channel is closed or disconnected.
Common situations: Users porting Binance-style post_only (maker-only) orders to IB, which expresses this via TIF/time-in-force semantics rather than a post_only flag; also occurs when the adapter's exec sender was shut down (adapter disconnect) mid-submission.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- dYdX only supports L2_MBP order book deltas, received {:?}
- FOK time in force is not supported by Hyperliquid
- Reduce-only is not supported for Hyperliquid HIP-4 outcomes:
- Failed to connect after {max_attempts} attempts
- Unknown IB security type: {value}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/eebe8b279d5dfdd0.
Report an issue: GitHub.