FuelLabs/fuel-core · error · crate::result::Error

Requested block height {} is greater than current synced hei

Error message

Requested block height {} is greater than current synced height {}

What it means

Raised by the remote block cache's get_block_range: the caller asked for blocks up to height `last`, but the locally persisted chain height is lower (or 0 when nothing is synced). Rather than returning a partial/empty range, the API fails with Error::db_error so callers notice they requested unsynced data.

Source

Thrown at crates/services/block_aggregator_api/src/db/remote_cache.rs:164

    }
}

impl<S> BlocksProvider for RemoteBlocksProvider<S>
where
    S: Send + Sync + 'static,
    S: KeyValueInspect<Column = Column>,
{
    type Block = Arc<[u8]>;
    type BlockRangeResponse = BlockRangeResponse;

    fn get_block_range(
        &self,
        first: BlockHeight,
        last: BlockHeight,
    ) -> crate::result::Result<Self::BlockRangeResponse> {
        let current_height = self.get_current_height()?.unwrap_or(BlockHeight::new(0));
        if last > current_height {
            Err(Error::db_error(anyhow!(
                "Requested block height {} is greater than current synced height {}",
                last,
                current_height
            )))
        } else {
            self.stream_blocks(first, last)
        }
    }

    fn get_current_height(&self) -> crate::result::Result<Option<BlockHeight>> {
        let height = self
            .local_persisted
            .as_structured_storage()
            .storage_as_ref::<LatestBlock>()
            .get(&())
            .map_err(|e| {
                Error::DB(anyhow!(e).context("while getting latest block height"))
            })?

View on GitHub (pinned to b9d4d170da)

Solutions

  1. Query get_current_height() first and clamp last to it (or last = min(last, current_height)) before requesting the range
  2. If the cache is empty or stale, wait for or trigger the initial sync, then retry the range request
  3. Drive range fetches from this cache's own current height, not from an external tip estimate
  4. If a true catch-up fetch is intended, use the stream_blocks path or an API that tolerates unsynced tails instead of get_block_range

Example fix

// before
let resp = source.get_block_range(first, requested_last)?; // fails when requested_last > synced

// after
let current = source.get_current_height()?.unwrap_or_default();
let last = requested_last.min(current);
if first > last { return Ok(empty_range_response()); }
let resp = source.get_block_range(first, last)?;
Defensive patterns

Strategy: validation

Validate before calling

let current = source.get_current_height()?.unwrap_or_default();
let last = requested_last.min(current);
if first > last {
    // nothing synced in range yet — wait for sync or return empty
    return Ok(BlockRangeResponse::default());
}
let resp = source.get_block_range(first, last)?;

Type guard

fn range_is_synced(source: &impl BlockSource, first: u32, last: u32) -> bool {
    source.get_current_height().ok().flatten().map_or(false, |h| last <= h.into())
}

Try / catch

match source.get_block_range(first, last) {
    Err(e) if e.to_string().contains("greater than current synced height") => {
        // cache behind: reschedule after sync progress instead of failing the job
        schedule_retry_after_sync();
    }
    other => other,
}

Prevention

When it happens

Trigger: Calling get_block_range(first, last) with last > current synced height — e.g., querying the chain tip height from a fresher source (or a hardcoded/future height) while this cache has not caught up. Note: no synced data at all yields current_height = 0, so any last > 0 fails.

Common situations: Aggregator started before the source node finished syncing; a fetch loop using the tip from another endpoint; restart after the local cache was wiped; height mismatch between the remote source and local persisted state.

Related errors


AI-assisted analysis of FuelLabs/fuel-core@b9d4d170da (2026-08-16). Data as JSON: /api/errors/cea13539ec941e3a. Report an issue: GitHub.