nautechsystems/nautilus_trader · error

Pool manifest address is invalid

Error message

Pool manifest address is invalid

What it means

Every manifest pool entry must contain valid 20-byte hex addresses for address, token0, token1, factory, and quote_contract. The validator parses each with Address::from_str and throws this error if any of the five fields is not parseable hex, so a single malformed field fails the whole pool entry.

Source

Thrown at crates/adapters/blockchain/src/rpc/verification.rs:1377

        );
        anyhow::ensure!(
            !token.name.trim().is_empty()
                && !token.symbol.trim().is_empty()
                && matches!(token.asset_role.as_str(), "base" | "quote" | "both"),
            "Token manifest identity or asset role is invalid"
        );
    }

    for pool in &manifest.pools {
        for address in [
            &pool.address,
            &pool.token0,
            &pool.token1,
            &pool.factory,
            &pool.quote_contract,
        ] {
            let address = Address::from_str(address)
                .map_err(|_| anyhow::anyhow!("Pool manifest address is invalid"))?;
            anyhow::ensure!(
                contract_addresses.contains(&address),
                "Pool manifest references an unpinned contract"
            );
        }
        anyhow::ensure!(
            pool.fee != 0 && pool.fee <= 1_000_000,
            "Pool fee is invalid"
        );
    }
    let mut call_edges = HashSet::new();
    for edge in &manifest.call_edges {
        anyhow::ensure!(
            matches!(
                edge.purpose.as_str(),
                "wrap" | "approve" | "swap_sell" | "swap_buy"
            ) && matches!(
                edge.call_type.as_str(),

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Set every pool field to a valid 0x + 40-hex-char contract address, resolving each reference to its on-chain contract
  2. Fix the specific field flagged by validating all five addresses (e.g. with cast or a small script) before re-running verification
  3. Regenerate pool entries from deployment tooling, which derives token0/token1/factory/quote_contract from the actual deployment

Example fix

// before
{"address": "0x<32-byte pool key>", "token0": "0xabc...", "token1": "0xdef...", "factory": "", "quote_contract": "0xquote..."}
// after
{"address": "0x1234...20bytes", "token0": "0xabc...", "token1": "0xdef...", "factory": "0xfactory...", "quote_contract": "0xquote..."}
Defensive patterns

Strategy: validation

Validate before calling

fn pool_addresses_ok(pool: &PoolEntry) -> bool {
    [&pool.address, &pool.token0, &pool.token1, &pool.factory, &pool.quote_contract]
        .iter().all(|a| Address::from_str(a).is_ok())
}
assert!(manifest.pools.iter().all(pool_addresses_ok));

Try / catch

match validate_manifest(&config) {
    Err(e) if e.to_string().contains("Pool manifest address is invalid") => {
        eprintln!("fix the malformed address among address/token0/token1/factory/quote_contract: {e}");
    }
    Err(e) => return Err(e),
    Ok(v) => v,
}

Prevention

When it happens

Trigger: Running manifest verification when any pool field — the pool's own address, either token address, the factory address, or the quote contract address — is empty, wrong length, or non-hex (e.g. a pool ID/hash pasted into an address field, or an off-chain identifier).

Common situations: Pasting a Uniswap V3 pool's 32-byte pool key or slot0 hash instead of its 20-byte contract address; copying the wrong chain's pool address; truncated hex from CSV export; referencing a pool before its factory/quote contract addresses were filled in.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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