nautechsystems/nautilus_trader · error · anyhow::Error
Invalid pool address '{}' failed with error: {:?}
Error message
Invalid pool address '{}' failed with error: {:?} What it means
Thrown in `handle_subscribe_command` when the instrument's symbol cannot be parsed as a valid Ethereum address via `validate_address`. The validation requires a `0x` prefix, exactly 42 characters, valid hex, and a correct EIP-55 checksum. The full instrument_id is included in the message.
Source
Thrown at crates/adapters/blockchain/src/data/client.rs:573
) -> anyhow::Result<()> {
match command {
DefiSubscribeCommand::Blocks(_cmd) => {
log::debug!("Processing subscribe blocks command");
Self::subscribe_block_feed(core_client, BlockFeedOwner::Explicit).await?;
Ok(())
}
DefiSubscribeCommand::Pool(cmd) => {
log::debug!(
"Processing subscribe pool command for {}",
cmd.instrument_id
);
if let Ok((_, dex)) = cmd.instrument_id.venue.parse_dex() {
let pool_address = validate_address(cmd.instrument_id.symbol.as_str())
.map_err(|e| {
anyhow::anyhow!(
"Invalid pool address '{}' failed with error: {:?}",
cmd.instrument_id,
e
)
})?;
// Subscribe to all pool event types
core_client
.subscription_manager
.subscribe_swaps(dex, pool_address);
core_client
.subscription_manager
.subscribe_burns(dex, pool_address);
core_client
.subscription_manager
.subscribe_mints(dex, pool_address);
core_client
.subscription_managerView on GitHub (pinned to 18893faf8b)
Solutions
- Pass the pool contract address in EIP-55 checksummed form as the instrument symbol (e.g. `0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Ed`).
- Re-checksum the address with a tool or `Address::parse_checksummed`/viem's `getAddress` before subscribing.
- Verify the symbol is exactly 42 characters, starts with 0x, and contains no whitespace or suffix.
- Confirm the address is the pool contract address, not a token or quote asset address.
Example fix
// before
let id = InstrumentId::from("USDC/WETH-0xb4e16d0168e52d35cacd2c6185b44281ec28c9ed@Uniswap");
// after (checksummed pool address as symbol)
let id = InstrumentId::from("0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Ed@Uniswap"); Defensive patterns
Strategy: validation
Validate before calling
// Rust
fn is_valid_pool_symbol(symbol: &str) -> bool {
symbol.starts_with("0x")
&& symbol.len() == 42
&& symbol[2..].chars().all(|c| c.is_ascii_hexdigit())
&& Address::parse_checksummed(symbol, None).is_ok()
} Try / catch
match Address::parse_checksummed(symbol, None) {
Ok(addr) => subscribe(addr),
Err(e) => log::error!("Rejecting subscription: '{symbol}' is not a checksummed pool address: {e}"),
} Prevention
- Always store and transmit addresses in EIP-55 checksummed form.
- Never use token tickers or names as instrument symbols for DEX pool subscriptions.
- Trim whitespace and avoid concatenating suffixes into the symbol field.
- Checksum-normalize addresses at system boundaries (config load, API input) once.
When it happens
Trigger: Subscribing to pool data with `SubscribeCommand` where `instrument_id.symbol` is not a well-formed checksummed 0x address (e.g. a plain token symbol like `USDC` or an all-lowercase address).
Common situations: Using a ticker symbol instead of the pool contract address; copying an address without its checksum (all lowercase/uppercase); truncated or pasted-with-spaces addresses; building instrument IDs like `0x...-Pool` with extra suffixes in the symbol.
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
- Invalid pool swap address '{}' failed with error: {:?}
- Invalid pool swap address: {}
- Invalid pool fee collect address: {}
- Invalid pool flash subscribe address: {}
- Invalid pool address: {}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/126a4df4282e34b8.
Report an issue: GitHub.