linera-io/linera-protocol · warning · ChainError
NotTimedOutYet
NotTimedOutYet
Error message
Not signing timeout certificate; current round times out at time {0} What it means
create_timeout_vote refuses to sign a timeout before the round's deadline: the validator's local time must have reached round_timeout, the timestamp stored when the round opened. The error returns that deadline so callers know when to come back.
Source
Thrown at linera-chain/src/manager.rs:394
&mut self,
chain_id: ChainId,
height: BlockHeight,
round: Round,
epoch: Epoch,
key_pair: Option<&ValidatorSecretKey>,
local_time: Timestamp,
) -> Result<bool, ChainError> {
let Some(key_pair) = key_pair else {
return Ok(false); // We are not a validator.
};
ensure!(
round == self.current_round(),
ChainError::WrongRound(self.current_round())
);
let Some(round_timeout) = *self.round_timeout.get() else {
return Err(ChainError::RoundDoesNotTimeOut);
};
ensure!(
local_time >= round_timeout,
ChainError::NotTimedOutYet(round_timeout)
);
if let Some(vote) = self.timeout_vote.get() {
if vote.round == round {
return Ok(false); // We already signed this timeout.
}
}
let value = Timeout::new(chain_id, height, epoch);
self.timeout_vote
.set(Some(Vote::new(value, round, key_pair)));
Ok(true)
}
/// Signs a `Timeout` certificate to switch to fallback mode.
///
/// This must only be called after verifying that the condition for fallback mode is
/// satisfied locally.View on GitHub (pinned to 6c226ddcb3)
Solutions
- Wait until the round_timeout timestamp returned in the error, then retry the leader-timeout query
- Verify clock synchronization (NTP) between client and validator
- Derive wait durations from the validator's own timestamps in ChainInfoResponse rather than local assumptions
Example fix
// before: immediate retry, fails with NotTimedOutYet(round_timeout)
client.request_leader_timeout(chain_id, height, round).await?;
// after: honor the deadline returned by the error (or chain info), then retry
match client.request_leader_timeout(chain_id, height, round).await {
Err(e) if matches!(e, ref x if x.is_not_timed_out_yet()) => {
let deadline = e.not_timed_out_yet_deadline().unwrap();
tokio::time::sleep_until(deadline.into()).await;
client.request_leader_timeout(chain_id, height, round).await?;
}
other => other?,
} Defensive patterns
Strategy: retry
Validate before calling
// Read the round deadline from chain info before asking for a timeout vote.
let info = client.chain_info(chain_id).await?;
if let Some(deadline) = info.manager.round_timeout {
if clock.now() < deadline {
tokio::time::sleep_until(deadline.into()).await;
}
}
client.request_leader_timeout(chain_id, height, round).await?; Type guard
fn is_not_timed_out_yet(e: &ChainError) -> bool {
matches!(e, ChainError::NotTimedOutYet(_))
} Try / catch
match client.request_leader_timeout(chain_id, height, round).await {
Err(ChainError::NotTimedOutYet(deadline)) => {
tokio::time::sleep_until(deadline.into()).await;
client.request_leader_timeout(chain_id, height, round).await?;
}
other => other?,
} Prevention
- Use the validator's timestamps (ChainInfoResponse), not local clock assumptions, to schedule timeout retries
- Keep client and validator clocks NTP-synchronized
- Bound retries with backoff so a misconfigured round duration surfaces quickly
When it happens
Trigger: vote_for_leader_timeout / create_timeout_vote invoked with local_time < round_timeout — requesting a timeout vote too early in the current round.
Common situations: Client clock ahead of the validator's clock; retry loop that does not respect the deadline; round_timeout duration configured longer on the validator than the client assumes; tests with mocked time.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- no signer found for owner ${owner}
- CannotRejectMessage
- Certificate justification commitment does not match its just
- Certificate unlocking round does not match the top of its ju
- Justification chain must lie in rounds strictly below the ce
AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22).
Data as JSON: /api/errors/180dadce34bd9bfe.
Report an issue: GitHub.