nautechsystems/nautilus_trader · error
Deployment manifest pool fee is invalid
Error message
Deployment manifest pool fee is invalid
What it means
Thrown when the deployment manifest's pool fee tier cannot be converted into a U24 (24-bit unsigned integer) fee value for a Uniswap V3 quote call. The library validates every manifest field before issuing on-chain calls, and a fee outside 0..16,777,215 (e.g. negative or > U24::MAX) fails this conversion. It aborts verification before any RPC request is made.
Source
Thrown at crates/adapters/blockchain/src/execution/client.rs:4985
.verify_gas_estimate(&wallet, &weth, U256::ZERO, &balance_call, block)
.await,
"Blockchain explicit-height gas capability",
)?;
let mut decisions = vec![
verification_decision(&storage, Some(block), Some(block)),
verification_decision(&gas, Some(block), Some(block)),
];
for pool in &manifest.pools {
let quote_contract = Address::from_str(&pool.quote_contract)
.with_context(|| "Deployment manifest quote capability target is invalid")?;
let token_in = Address::from_str(&pool.token0)
.with_context(|| "Deployment manifest quote input token is invalid")?;
let token_out = Address::from_str(&pool.token1)
.with_context(|| "Deployment manifest quote output token is invalid")?;
let fee = U24::try_from(pool.fee)
.map_err(|_| anyhow::anyhow!("Deployment manifest pool fee is invalid"))?;
let quote = required_verification(
verification
.verify_quote_exact_input_single(
"e_contract,
token_in,
token_out,
U256::from(1u64),
fee,
block,
)
.await,
"Blockchain explicit-height quote capability",
)?;
decisions.push(verification_decision("e, Some(block), Some(block)));
}
let trace = required_verification(
verification.verify_call_trace_capability().await,View on GitHub (pinned to 18893faf8b)
Solutions
- Check pool.fee in the deployment manifest; valid Uniswap V3 tiers are 100, 500, 3000, or 10000
- Ensure the fee is a non-negative integer encoded as a string or integer, not a float
- Verify the manifest generator/writer uses U24-compatible fee values (0..=16777215)
- Regenerate the deployment manifest from the pool address on-chain if the fee is unknown
Example fix
// before
"pool": { "token0": "0xA0b8...", "token1": "0xdAC1...", "fee": 0.003 }
// after
"pool": { "token0": "0xA0b8...", "token1": "0xdAC1...", "fee": 3000 } Defensive patterns
Strategy: validation
Validate before calling
const U24_MAX: u32 = 16_777_215;
fn validate_pool_fee(fee: &str) -> Result<(), String> {
let v: u32 = fee.parse().map_err(|_| "fee must be a non-negative integer")?;
if v > U24_MAX { return Err(format!("fee {v} exceeds U24 max {U24_MAX}")); }
Ok(())
} Type guard
fn is_valid_fee(fee: u32) -> bool { fee <= 16_777_215 } Prevention
- Keep fee tiers as canonical integers (100/500/3000/10000) in the manifest
- Never encode fee as float or basis points
- Schema-validate the manifest before deployment verification
- Regenerate manifests from on-chain pool state rather than hand-editing
When it happens
Trigger: Parsing a deployment manifest whose pool.fee is negative or exceeds U24::MAX (16,777,215) during exact-input-single quote verification in verify_deployment/verification flow.
Common situations: Manifest typo'd fee tiers (e.g. 5000000 instead of 500000, or 3000000 for 0.3%), fees entered in basis points or as floats, JSON hand-edited with a value above 16,777,215, or a manifest generated for a non-V3 fee convention.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- Pool {instrument_id} references factory {}, expected registe
- request_rate_per_second must be greater than zero
- order_request_rate_per_second must be greater than zero
- heartbeat_secs must be positive when set
- heartbeat_timeout_secs must cover at least two server heartb
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/55ffced02c67c0cf.
Report an issue: GitHub.