linera-io/linera-protocol · error · ChainError
BlockHeightOverflow
BlockHeightOverflow
Error message
Sequence numbers above the maximal value are not usable for blocks
What it means
Guard in ChainManager::check_proposed_block: a proposed block's height must be strictly below BlockHeight::MAX (u64::MAX) so that incrementing the height after certification can never fail. A block at the maximal height could be certified but never extended, deadlocking the chain, so the proposal is refused up front.
Source
Thrown at linera-chain/src/manager.rs:296
///
/// Having a leader timeout certificate in any given round causes the next one to become
/// current. Seeing a validated block certificate or a valid proposal in any round causes that
/// round to become current, unless a higher one already is.
pub fn current_round(&self) -> Round {
*self.current_round.get()
}
/// Verifies that a proposed block is relevant and should be handled.
pub fn check_proposed_block(&self, proposal: &BlockProposal) -> Result<Outcome, ChainError> {
let new_block = &proposal.content.block;
let new_round = proposal.content.round;
if let Some(old_proposal) = self.proposed.get() {
if old_proposal.content == proposal.content {
return Ok(Outcome::Skip); // We have already seen this proposal; nothing to do.
}
}
// When a block is certified, incrementing its height must succeed.
ensure!(
new_block.height < BlockHeight::MAX,
ChainError::BlockHeightOverflow
);
let current_round = self.current_round();
match new_round {
// The proposal from the fast round may still be relevant as a locking block, so
// we don't compare against the current round here.
Round::Fast => {}
Round::MultiLeader(_) | Round::SingleLeader(0) => {
// If the fast round has not timed out yet, only a super owner is allowed to open
// a later round by making a proposal.
ensure!(
self.is_super(&proposal.owner()) || !current_round.is_fast(),
ChainError::WrongRound(current_round)
);
// After the fast round, proposals older than the current round are obsolete.
ensure!(
new_round >= current_round,View on GitHub (pinned to 6c226ddcb3)
Solutions
- If hit in tests or fuzzing, use a fresh chain or reset the fixture instead of extending one at u64::MAX
- If ever hit in production, the chain is exhausted and cannot be extended further; migrate state to a new chain
Defensive patterns
Strategy: validation
Validate before calling
// Refuse to build or submit a proposal at the maximal height.
if block.height >= BlockHeight::MAX {
return Err(my::Error::ChainExhausted);
} Type guard
fn is_block_height_overflow(e: &ChainError) -> bool {
matches!(e, ChainError::BlockHeightOverflow)
} Prevention
- Never construct blocks with u64::MAX heights outside fuzz tests
- In long-running test suites, use fresh chains when a chain's height approaches artificial limits
When it happens
Trigger: Submitting (via try_handle_block_proposal) a block proposal whose block.height equals BlockHeight::MAX.
Common situations: Practically unreachable in production because it requires 2^64 blocks on one chain; occasionally produced by fuzzers or unit tests that construct blocks at extreme heights.
Related errors
- no signer found for owner ${owner}
- CannotRejectMessage
- UnexpectedBlockHeight
- InvalidBlockChaining
- FalseFirstRoundAttestation
AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22).
Data as JSON: /api/errors/b4d10c09efdc264c.
Report an issue: GitHub.