nautechsystems/nautilus_trader · warning · anyhow::Error

Insufficient liquidity: requested {amount_out_requested}, av

Error message

Insufficient liquidity: requested {amount_out_requested}, available {actual_out}

What it means

`validate_exact_output` compares the pool's computed output amount (`get_output_amount()`, a `U256`) against the caller's `amount_out_requested`. When the pool cannot deliver the requested output given the configured input, it bails with this message showing both amounts. It is an expected, caller-facing outcome for exact-output style trades on pools with limited reserves.

Source

Thrown at crates/model/src/defi/pool_analysis/quote.rs:261

    /// Returns an error if the actual slippage exceeds the maximum slippage tolerance.
    pub fn validate_slippage_tolerance(&mut self, max_slippage_bps: u32) -> anyhow::Result<()> {
        let actual_slippage = self.get_slippage_bps()?;
        if actual_slippage > max_slippage_bps {
            anyhow::bail!(
                "Slippage {actual_slippage} bps exceeds tolerance {max_slippage_bps} bps"
            );
        }
        Ok(())
    }

    /// Validates that the quote satisfied an exact output request.
    ///
    /// # Errors
    /// Returns error if the actual output is less than the requested amount.
    pub fn validate_exact_output(&self, amount_out_requested: U256) -> anyhow::Result<()> {
        let actual_out = self.get_output_amount();
        if actual_out < amount_out_requested {
            anyhow::bail!(
                "Insufficient liquidity: requested {amount_out_requested}, available {actual_out}"
            );
        }
        Ok(())
    }

    /// Converts this quote into a [`PoolSwap`] event with the provided metadata.
    ///
    /// # Returns
    /// A [`PoolSwap`] event containing both the quote data and provided metadata
    #[must_use]
    #[expect(clippy::too_many_arguments)]
    pub fn to_swap_event(
        &self,
        chain: SharedChain,
        dex: SharedDex,
        pool_identifier: PoolIdentifier,
        block: BlockPosition,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Increase the input amount or recompute it so the pool can output `amount_out_requested`.
  2. Lower `amount_out_requested` to what the pool can actually deliver.
  3. Verify token decimals and scaling of `amount_out_requested` (U256 raw units).
  4. Quote a different/higher-liquidity pool for the same pair.

Example fix

// before
let requested = U256::from(1_000_000_000_000_000_000u64); // assumes 18 decimals
quote.validate_exact_output(requested)?;
// after
let actual = quote.get_output_amount();
if actual < requested {
    // adapt the trade to the achievable output
    let requested = actual;
}
quote.validate_exact_output(requested)?;
Defensive patterns

Strategy: validation

Validate before calling

let actual_out = quote.get_output_amount();
if actual_out < amount_out_requested {
    // adjust requested amount down or increase input before validating
}

Try / catch

quote.validate_exact_output(requested).map_err(|e| {
    if e.to_string().contains("Insufficient liquidity") {
        // fall back to partial fill or larger input
    }
    e
})?;

Prevention

When it happens

Trigger: Calling `validate_exact_output(amount_out_requested)` where `get_output_amount()` returns less than the requested `U256` amount; typically when the input amount is too small, the pool is thinly capitalized, or the requested amount uses wrong token decimals/scale.

Common situations: Exact-output arbitrage sizing against low-liquidity pools; requesting amounts scaled with the wrong decimals (e.g. 6 vs 18); quoting across the wrong pool variant; U256 vs native integer unit mismatches in the requested amount.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/61503f1fc07174d2. Report an issue: GitHub.