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
- Query get_current_height() first and clamp last to it (or last = min(last, current_height)) before requesting the range
- If the cache is empty or stale, wait for or trigger the initial sync, then retry the range request
- Drive range fetches from this cache's own current height, not from an external tip estimate
- 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
- Always derive range bounds from the cache's own get_current_height(), never an external tip
- On cold start, wait for initial sync before issuing range queries
- Treat this error as a backpressure signal: retry later rather than surfacing it to users
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
- Could not convert upload root to Bytes32: {}
- Could not convert witness_index to u16: {}
- Could not convert subsection_index to u16: {}
- Could not convert subsections_number to u16: {}
- Could not convert proof_set entry to Bytes32: {}
AI-assisted analysis of FuelLabs/fuel-core@b9d4d170da (2026-08-16).
Data as JSON: /api/errors/cea13539ec941e3a.
Report an issue: GitHub.