nautechsystems/nautilus_trader · error
Cannot decode inverted price from zero sqrt_price_x96
Error message
Cannot decode inverted price from zero sqrt_price_x96
What it means
In the inverted price branch (decimal_diff < 0), the denominator is sqrt_price_x96^2. A zero sqrt_price_x96 would mean division by zero, so the function explicitly rejects it with this error. Uniswap V3 pools can transiently report sqrt_price_x96 == 0 (empty/liquidity-less pool state), which makes an inverted token0/token1 price mathematically undefined.
Source
Thrown at crates/model/src/defi/tick_map/sqrt_price_math.rs:416
if price_square > max_square {
U256::ZERO
} else {
let price_square = U256::checked_from_limbs_slice(price_square.as_limbs())
.ok_or_else(|| {
anyhow::anyhow!("Inverted price denominator exceeds U256 range")
})?;
let denominator =
price_square
.checked_mul(decimal_adjustment)
.ok_or_else(|| {
anyhow::anyhow!("Inverted price denominator exceeds U256 range")
})?;
FullMath::mul_div(numerator, U256::from(1), denominator)?
}
} else {
let price_square: U512 = sqrt_price.widening_mul(sqrt_price);
anyhow::ensure!(
!price_square.is_zero(),
"Cannot decode inverted price from zero sqrt_price_x96"
);
let numerator = U512::from(divisor_base)
.checked_mul(U512::from(decimal_adjustment))
.and_then(|value| value.checked_mul(U512::from(fixed_scalar)))
.ok_or_else(|| anyhow::anyhow!("Inverted price numerator exceeds U512 range"))?;
let quotient = numerator / price_square;
U256::checked_from_limbs_slice(quotient.as_limbs())
.ok_or_else(|| anyhow::anyhow!("Inverted price exceeds U256 range"))?
}
} else if decimal_diff >= 0 {
FullMath::mul_div_scaled(
sqrt_price,
sqrt_price,
divisor_base,
&[fixed_scalar, decimal_adjustment],
)?View on GitHub (pinned to 18893faf8b)
Solutions
- Check sqrt_price_x96 != 0 before calling and skip the pool or default the price to zero.
- Handle the error by treating the pool as unpriced (no liquidity) rather than retrying.
- If a price is required, wait until the pool has been initialized (slot0.sqrtPriceX96 > 0).
Example fix
// before
let price = decode_sqrt_price_x96_to_price_tokens_adjusted(sqrt_price_x96, d0, d1, true)?;
// after
if sqrt_price_x96.is_zero() {
// unpriced/uninitialized pool
return Ok(Price::zero(FIXED_PRECISION));
}
let price = decode_sqrt_price_x96_to_price_tokens_adjusted(sqrt_price_x96, d0, d1, true)?; Defensive patterns
Strategy: validation
Validate before calling
if sqrt_price_x96.is_zero() { return Ok(Price::zero(FIXED_PRECISION)); } Type guard
fn pool_is_priced(sqrt_price_x96: U160) -> bool { !sqrt_price_x96.is_zero() } Try / catch
match decode_sqrt_price_x96_to_price_tokens_adjusted(sp, d0, d1, true) {
Ok(p) => p,
Err(e) if e.to_string().contains("zero sqrt_price_x96") => {
tracing::debug!("pool unpriced (zero sqrt price)");
Price::zero(FIXED_PRECISION)
}
Err(e) => return Err(e),
} Prevention
- Always check sqrt_price_x96 != 0 when inverting a price
- Treat zero sqrt price as 'pool has no liquidity', not as a fatal error
- Initialize pool state from slot0 before decoding prices
When it happens
Trigger: Calling decode_sqrt_price_x96_to_price_tokens_adjusted with invert=true, token0_decimals < token1_decimals, and sqrt_price_x96 = 0 (as via compute or spot_price).
Common situations: Subscribing to a freshly created Uniswap V3 pool before liquidity is added; a pool after all liquidity is removed; decoding on-chain slot0 data for an uninitialized pool.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Cannot calculate price impact, the spot price before is not
- Cannot calculate slippage, the spot price before is not set
- Cannot quote swap with zero amount
- Price limit must be less than current price for zero_for_one
- Price limit must be greater than current price for one_for_z
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/4a80693f0a715ec9.
Report an issue: GitHub.