nautechsystems/nautilus_trader · error · anyhow::Error

Failed to sync blocks: {e}

Error message

Failed to sync blocks: {e}

What it means

Wraps errors from `data_client.sync_blocks_checked(from_block, to_block)` in `run_sync_blocks`. After chain initialization, the CLI backfills blocks through the node RPC with consistency checks, and any RPC failure, missing block data, database write failure, or consistency-check violation is reported under this message. The command then aborts.

Source

Thrown at crates/cli/src/blockchain/sync.rs:157

        database.username,
        database.password,
        database.database,
    );
    let config = BlockchainDataClientConfig::builder()
        .chain(chain.clone())
        .http_rpc_url(String::new().into()) // we dont need to http rpc url for block syncing
        .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
        .sync_blocks_checked(from_block, to_block)
        .await
        .map_err(|e| anyhow::anyhow!("Failed to sync blocks: {e}"))?;

    Ok(())
}

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Point at an archive node if syncing blocks older than the node's retained history.
  2. Reduce the range via explicit --from-block/--to-block and sync in batches, resuming from the last successful block.
  3. Retry after transient RPC/network errors; verify node health and sync status first.
  4. Check Postgres/cache database connectivity, credentials, and disk space.
  5. Enable debug logging to read the inner `{e}` and address the specific failing call.

Example fix

// before
nautilus blockchain sync blocks --chain ethereum   # full 0..latest against rate-limited RPC
// after
nautilus blockchain sync blocks --chain ethereum --from-block 18000000 --to-block 18001000
Defensive patterns

Strategy: retry

Validate before calling

// ensure the node can serve the requested range
let latest = eth_client.block_number().await?;
let earliest = eth_client.get_block_by_number(1).await.is_ok();
if !earliest { eprintln!("node lacks historical state; use an archive node"); }

Try / catch

match data_client.sync_blocks_checked(from_block, to_block).await {
    Ok(()) => info!("block sync complete"),
    Err(e) if is_transient(&e) => { eprintln!("transient RPC error, retrying: {e:#}"); }
    Err(e) => { eprintln!("block sync failed: {e:#}; narrow --from-block/--to-block and retry"); }
}

Prevention

When it happens

Trigger: Running `nautilus blockchain sync blocks` when the node RPC fails mid-range, the requested from/to block range exceeds provider limits or pruned history, the node returns inconsistent data failing the checked sync, or the Postgres/cache write path fails.

Common situations: Requesting very old blocks from a full (non-archive) node that has pruned state; syncing a huge range in one shot against a rate-limited endpoint; Postgres down or disk full during backfill; node restarting or reorging while the sync is running.

Related errors


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