nautechsystems/nautilus_trader · error · anyhow::Error
Failed to sync pools: {e}
Error message
Failed to sync pools: {e} What it means
Wraps errors from `data_client.sync_exchange_pools(&dex_type, 0, None, reset)` after the DEX exchange was successfully registered in `run_sync_dex`. Pool sync walks on-chain factory/pool events from block 0 to the latest block through the node RPC, so RPC failures, reorg-related errors, or client-side database write failures are reported here. The CLI aborts the command.
Source
Thrown at crates/cli/src/blockchain/sync.rs:120
.http_rpc_url(rpc_http_url.into())
.maybe_multicall_calls_per_rpc_request(multicall_calls_per_rpc_request)
.use_hypersync_for_live_data(true)
.postgres_cache_database_config(postgres_connect_options)
.build();
let cancellation_token = tokio_util::sync::CancellationToken::new();
let mut data_client = BlockchainDataClientCore::new(config, None, None, cancellation_token);
data_client.initialize_cache_database().await;
data_client.cache.initialize_chain().await;
data_client
.register_dex_exchange(dex_type)
.await
.map_err(|e| anyhow::anyhow!("Failed to register DEX exchange: {e}"))?;
// We want to have full pool sync, so from 0 to last.
data_client
.sync_exchange_pools(&dex_type, 0, None, reset)
.await
.map_err(|e| anyhow::anyhow!("Failed to sync pools: {e}"))?;
Ok(())
}
pub(crate) async fn run_sync_blocks(
chain: String,
from_block: Option<u64>,
to_block: Option<u64>,
database: DatabaseConfig,
) -> anyhow::Result<()> {
let chain = Chain::from_chain_name(&chain)
.ok_or_else(|| anyhow::anyhow!("Invalid chain name: {chain}"))?;
let chain = Arc::new(chain.to_owned());
let from_block = from_block.unwrap_or(0);
let postgres_connect_options = get_postgres_connect_options(
database.host,
database.port,View on GitHub (pinned to 18893faf8b)
Solutions
- Retry the command; the sync is resumable/resettable — use the reset flag only if data is inconsistent.
- Switch to a paid/dedicated or local archive node to avoid rate limiting and pruned-state errors during the 0-to-latest backfill.
- Check Postgres/cache database connectivity and disk space; a long sync can fail on DB write errors.
- Sync a smaller block range (or a single DEX) first to isolate whether the failure is RPC- or data-related.
- Inspect the inner `{e}` message with debug logging to target the actual failing call.
Defensive patterns
Strategy: retry
Validate before calling
// check DB reachability and node height before syncing
let height = eth_client.block_number().await?;
let pg = sqlx::postgres::PgPool::connect(&db_url).await?;
println!("node at block {height}, db ok"); Try / catch
loop {
match data_client.sync_exchange_pools(&dex_type, from, None, reset).await {
Ok(()) => break,
Err(e) if is_transient(&e) => { backoff().await; continue; }
Err(e) => { eprintln!("pool sync failed permanently: {e:#}"); break; }
}
} Prevention
- Use archive/dedicated RPC endpoints for full-history pool backfills.
- Sync in block-range chunks so failures resume from a known point.
- Monitor DB connections/disk during long syncs.
- Avoid resetting cache unless data is known inconsistent.
- Rate-limit RPC calls to stay under provider quotas.
When it happens
Trigger: Running `nautilus blockchain sync dex` when the node RPC drops mid-backfill, the block range 0..latest is too large for the provider's limits, the chain is reorganizing, or writing pools to the cache database fails.
Common situations: Long initial full-history sync against public rate-limited RPC endpoints (Infura/Alchemy free tier); local node pruning historical state; Postgres down or connection pool exhausted during a long sync; network interruption during a multi-hour backfill.
Related errors
- Failed to sync blocks: {e}
- Failed to register DEX exchange: {e}
- Failed to register DEX exchange: {e}
- Failed to sync pool events: {e}
- Database is not initialized
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/856bb43263407c8d.
Report an issue: GitHub.