nautechsystems/nautilus_trader · error
cannot advance RPC profiler from block {} to earlier block {
Error message
cannot advance RPC profiler from block {} to earlier block {to_block} What it means
advance_pool_profiler_from_rpc_snapshot moves a profiler forward from its last processed event watermark to to_block. If the requested to_block is earlier than the current watermark (from_position.number), time would go backwards, which the API forbids.
Source
Thrown at crates/adapters/blockchain/src/data/core.rs:1613
/// The profiler must come from [`Self::bootstrap_pool_profiler_from_rpc_snapshot`] or an earlier
/// call to this method. This keeps one command incremental without trusting an unproven stored
/// snapshot as the topology source.
///
/// # Errors
///
/// Returns an error if the profiler has no RPC snapshot watermark, the target precedes that
/// watermark, event streaming fails, or RPC hydration fails.
pub async fn advance_pool_profiler_from_rpc_snapshot(
&mut self,
profiler: PoolProfiler,
to_block: u64,
) -> anyhow::Result<(PoolProfiler, bool)> {
let from_position = profiler.last_processed_event.clone().ok_or_else(|| {
anyhow::anyhow!("cannot advance an RPC profiler without a snapshot watermark")
})?;
if to_block < from_position.number {
anyhow::bail!(
"cannot advance RPC profiler from block {} to earlier block {to_block}",
from_position.number
);
}
self.construct_pool_profiler_from_hypersync_rpc(profiler, Some(from_position), to_block)
.await
}
async fn seed_pool_profiler_from_latest_snapshot(
&self,
pool: &SharedPool,
to_block: u64,
) -> anyhow::Result<(PoolProfiler, Option<BlockPosition>)> {
let mut profiler = PoolProfiler::new(pool.clone());
let from_position = match self
.cacheView on GitHub (pinned to 18893faf8b)
Solutions
- Query the profiler's last_processed_event and request to_block >= that block number
- If you truly need history before the watermark, rebuild a fresh profiler via bootstrap_pool_profiler_from_rpc_snapshot
- Ensure only one caller advances a given profiler and targets are monotonic
Example fix
// before let to_block = 19_000_000; // older than profiler watermark client.advance_pool_profiler_from_rpc_snapshot(profiler, to_block).await?; // after let to_block = profiler.last_processed_event.as_ref().unwrap().number.max(19_000_000); client.advance_pool_profiler_from_rpc_snapshot(profiler, to_block).await?;
Defensive patterns
Strategy: validation
Validate before calling
let from = profiler.last_processed_event.as_ref().map(|p| p.number).unwrap_or(0);
assert!(to_block >= from, "to_block {to_block} precedes watermark {from}");
client.advance_pool_profiler_from_rpc_snapshot(profiler, to_block).await?; Type guard
fn can_advance(p: &PoolProfiler, to_block: u64) -> bool {
p.last_processed_event.as_ref().is_some_and(|w| to_block >= w.number)
} Try / catch
match client.advance_pool_profiler_from_rpc_snapshot(profiler, to_block).await {
Err(e) if e.to_string().contains("to earlier block") => {
log::warn!("profiler already beyond {to_block}; nothing to do");
Ok((profiler.clone(), false))
}
r => r,
} Prevention
- Always read last_processed_event before choosing to_block
- Make advance calls monotonic per profiler (single owner)
- Never reuse cached to_block values across profiler instances
When it happens
Trigger: Calling advance_pool_profiler_from_rpc_snapshot with to_block lower than profiler.last_processed_event.number, e.g. reusing a stale/older target block or mixing profilers across chains.
Common situations: Caching a to_block from a previous request and replaying it against an already-advanced profiler; concurrent callers advancing the same profiler with out-of-order blocks; recovering from a backup with an older target.
Related errors
- Database is not initialized, so we cannot properly bootstrap
- Pool is not initialized and it doesn't contain initial price
- Database is not initialized, so we cannot bootstrap the pool
- Pool state at block {} has no ingestion-time block hash; ref
- Pool state at block {} has an invalid partial snapshot water
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/94c9b5aa463d06b7.
Report an issue: GitHub.