nautechsystems/nautilus_trader · error
Restored pool {instrument_id} references factory {}, expecte
Error message
Restored pool {instrument_id} references factory {}, expected registered factory {factory} What it means
restore_swap_plan checks that the restored pool's DEX factory address equals the Uniswap V3 factory registered with this execution client (self.uniswap_v3_factory()). A mismatch means the instrument resolves to a pool created by a different factory than the one this client is configured to interact with, so the swap plan is rejected. This prevents routing swaps through a pool the client's configured router/factory does not govern.
Source
Thrown at crates/adapters/blockchain/src/execution/client.rs:1098
let fee = U24::try_from(
pool.fee
.ok_or_else(|| anyhow::anyhow!("Restored pool {instrument_id} has no fee"))?,
)?;
let quote_token = pool.get_quote_token();
let quote_currency = Currency::new_checked(
"e_token.symbol,
quote_token.decimals,
0,
"e_token.name,
CurrencyType::Crypto,
)?;
let (token_in, token_out) = swap_token_pair(
order.order_side(),
pool.get_base_token().address,
quote_token.address,
)?;
let factory = self.uniswap_v3_factory()?;
anyhow::ensure!(
pool.dex.factory == factory,
"Restored pool {instrument_id} references factory {}, expected registered factory {factory}",
pool.dex.factory
);
Ok(SwapPlan {
order,
quote_currency,
pool,
instrument_id,
pool_address,
router: Address::from_str(&intent.transaction_to)?,
factory,
weth: self.weth_address,
token_in,
token_out,
fee,
amount_in,View on GitHub (pinned to 18893faf8b)
Solutions
- Restore the original factory configuration so the registered factory matches the pool's dex.factory recorded at persist time.
- Re-register the instrument against the currently configured factory (or update the instrument's dex metadata) if the pool should migrate.
- Resolve/cancel the stale intent before switching factories or networks, then re-issue the trade.
- Verify chain/network config: a same-named instrument on a different chain will carry a different factory address.
Example fix
// before factory_address = "0xDifferentFactory" // after (factory that created the persisted pool) factory_address = "0xOriginalUniswapV3Factory"
Defensive patterns
Strategy: validation
Validate before calling
let factory = client.uniswap_v3_factory()?;
let pool = client.resolve_pool(&instrument_id)?;
if pool.dex.factory != factory {
eprintln!("pool factory {} != configured factory {factory}; align factory config with the instrument's DEX", pool.dex.factory);
} Type guard
fn factory_matches(pool: &Pool, configured_factory: Address) -> bool {
pool.dex.factory == configured_factory
} Prevention
- Keep the Uniswap V3 factory address stable per environment; plan intent-draining before changing it
- Register instruments only from DEXes matching the configured factory
- Verify chain/network addresses when forking or migrating deployments
- Resolve stale intents before switching factories
When it happens
Trigger: reconcile_unresolved_execution or build_execution_verification_migration calls restore_swap_plan and pool.dex.factory differs from the configured uniswap_v3_factory address for intent.instrument_id. Occurs when the factory contract address in config changed between persisting and restoring, or the instrument was registered against a different DEX/factory (fork, deployment, another V3-like DEX).
Common situations: Changing the Uniswap V3 factory address in config (e.g. moving to a fork like Base deployment) while old intents reference the previous factory; registering instruments from multiple V3-fork DEXes but reconciling with a client pinned to one factory; pointing the node at a different network with different contract addresses.
Understand the failure class
Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.
Related errors
- Persisted pool {pool_address} does not match restored pool {
- Finalized transaction {} emitted {} Swap logs; expected exac
- Persisted swap intent has no pool address
- Persisted swap intent has no input amount
- Restored pool {instrument_id} has no fee
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/e529924d6502eeb4.
Report an issue: GitHub.