nautechsystems/nautilus_trader · error
Local quote for {instrument_id} produced a zero quote input
Error message
Local quote for {instrument_id} produced a zero quote input What it means
For SELL orders the local quote must fill the full base_amount; the code compares the quote's filled amount (I256) with the order's base_amount and bails when they differ. Note the source excerpt shows this check fires with a distinct "zero quote input" message at line 1684 when the quote input computed for the local quote is zero — meaning the simulated swap had nothing to fill against, typically because the computed input amount was zero.
Source
Thrown at crates/adapters/blockchain/src/execution/client.rs:1684
}
let profiler_position = profiler.last_processed_event.clone().ok_or_else(|| {
anyhow::anyhow!("Pool profiler for {instrument_id} has processed no events")
})?;
let zero_for_one = token_in == pool.token0.address;
let (amount_in, quoted_amount_out) = match order.order_side() {
OrderSide::Sell => {
let quote = profiler
.swap_exact_in(base_amount, zero_for_one, None)
.map_err(|e| anyhow::anyhow!("Swap quote failed for {instrument_id}: {e}"))?;
let amount_filled = if zero_for_one {
quote.amount0
} else {
quote.amount1
};
if amount_filled != I256::from(base_amount) {
anyhow::bail!(
"Local quote for {instrument_id} filled {amount_filled} of the {base_amount} order amount; pool liquidity cannot fill the order"
);
}
(base_amount, exact_output_amount("e, zero_for_one)?)
}
OrderSide::Buy => {
let quote = profiler
.swap_exact_out(base_amount, zero_for_one, None)
.map_err(|e| anyhow::anyhow!("Swap quote failed for {instrument_id}: {e}"))?;
let amount_in = quote.get_input_amount();
if amount_in.is_zero() {
anyhow::bail!("Local quote for {instrument_id} produced a zero quote input");
}
let ceiling = quote_spend_ceiling.ok_or_else(|| {
anyhow::anyhow!(
"No `quote_spend_limits` entry for BUY token pair {token_in} -> {token_out}"
)
})?;View on GitHub (pinned to 18893faf8b)
Solutions
- Increase the order quantity so the raw amount is non-zero and representable at base token decimals.
- Check the pool's liquidity — use a more liquid pool or split the order.
- Verify the pool profiler state is fresh (re-sync) so the local quote simulates against current liquidity.
Example fix
// before let qty = 0.0000001; // rounds to 0 raw units client.submit_order(cmd, &order)?; // after let raw = quantity_to_raw_amount(qty, base_token.decimals)?; assert!(raw > U256::zero(), "order quantity rounds to zero"); client.submit_order(cmd, &order)?;
Defensive patterns
Strategy: validation
Validate before calling
// Rust
let raw = quantity_to_raw_amount(order.quantity(), base_token.decimals)?;
if raw.is_zero() {
return Err(anyhow::anyhow!("order quantity rounds to zero raw units"));
} Prevention
- Enforce a minimum order size in raw units per token decimals.
- Check pool liquidity before submitting large orders.
- Keep profiler state fresh to avoid degenerate quotes.
When it happens
Trigger: submit_order (SELL path) where the local quote simulation computes a zero input amount, or where amount_filled != base_amount because pool liquidity cannot fill the order size.
Common situations: Very small order sizes that round to zero raw units; an illiquid or empty pool that cannot fill the order; stale profiler state producing a degenerate quote.
Related errors
- No deployed bytecode at {description} address {address}
- RPC tick {tick_value} does not match positions: derived gros
- HyperSync parsing of swap event is not defined in this dex:
- Unsupported order type {}; only Market is supported
- Unsupported order side {}; only Buy and Sell are supported
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/ad37dab908c6caff.
Report an issue: GitHub.