linera-io/linera-protocol · warning · ChainError
InsufficientRoundStrict
InsufficientRoundStrict
Error message
Round number should be greater than {0:?} What it means
The round of a validator's validation votes is only allowed to increase: check_proposed_block rejects any proposal whose round is not strictly greater than the round of the manager's latest validated vote. This keeps signed validation votes monotonic.
Source
Thrown at linera-chain/src/manager.rs:328
ChainError::WrongRound(current_round)
);
// After the fast round, proposals older than the current round are obsolete.
ensure!(
new_round >= current_round,
ChainError::InsufficientRound(new_round)
);
}
Round::SingleLeader(_) | Round::Validator(_) => {
// After the first single-leader round, only proposals from the current round are relevant.
ensure!(
new_round == current_round,
ChainError::WrongRound(current_round)
);
}
}
// The round of our validation votes is only allowed to increase.
if let Some(vote) = self.validated_vote() {
ensure!(
new_round > vote.round,
ChainError::InsufficientRoundStrict(vote.round)
);
}
// A proposal that isn't newer than the locking block is not relevant anymore.
if let Some(locking_block) = self.locking_block.get() {
ensure!(
locking_block.round() < new_round,
ChainError::MustBeNewerThanLockingBlock(new_block.height, locking_block.round())
);
}
// If we have voted to confirm a block, we may only vote to validate a *different* block
// if a validated block certificate justifies it from a round strictly after our
// confirmation. The validation vote will then sign the unlocking round `certificate.round`,
// and since our confirmation is in an earlier round, the claim "I have not voted to confirm
// a different block in any round at or above the unlocking round" stays truthful.
//
// Re-validating the very block we confirmed is also allowed, but the certificate mustView on GitHub (pinned to 6c226ddcb3)
Solutions
- Move to a strictly higher round (collect timeout votes/certificates to advance the round) before re-proposing
- Drop the conflicting proposal; it cannot be validated at or below the vote round
Defensive patterns
Strategy: validation
Validate before calling
let info = client.chain_info(chain_id).await?;
if let Some(vote) = info.manager.validated_vote() {
if proposal.content.round <= vote.round {
// Validation votes only move forward: advance the round first.
return advance_round_via_timeouts(&client, chain_id).await;
}
} Type guard
fn is_insufficient_round_strict(e: &ChainError) -> bool {
matches!(e, ChainError::InsufficientRoundStrict(_))
} Prevention
- Never resubmit a proposal at or below the round you last voted in
- Use leader timeouts to advance rounds before re-proposing conflicting blocks
When it happens
Trigger: A proposal (often conflicting or a duplicate) arrives with round <= validated_vote.round while the manager has already voted to validate a block in that round.
Common situations: Two leaders active in the same round; retrying a proposal after the validator already voted on another block in that round; client resubmitting from stale state.
Related errors
- The new proposal's round must be greater than the original's
- Signatures in a certificate must be from different validator
- WrongRound
- InsufficientRound
- MustBeNewerThanLockingBlock
AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22).
Data as JSON: /api/errors/f31aa9525496e2ba.
Report an issue: GitHub.