risingwavelabs/risingwave · error
truncate at {:?} but latest offset is {:?}
Error message
truncate at {:?} but latest offset is {:?} What it means
Guard in the in-memory log store's truncate: the requested truncate offset exceeds the latest written offset in the buffer. One cannot truncate data that has not been written yet, so out-of-order or over-advancing truncation is rejected with this error.
Source
Thrown at src/stream/src/common/log_store_impl/in_mem.rs:244
None => Err(anyhow!("end of log stream")),
},
AwaitingTruncate { .. } => std::future::pending().await,
}
}
fn truncate(&mut self, offset: TruncateOffset) -> LogStoreResult<()> {
// check the truncate offset is higher than prev truncate offset
if self.truncate_offset >= offset {
return Err(anyhow!(
"truncate offset {:?} but prev truncate offset is {:?}",
offset,
self.truncate_offset
));
}
// check the truncate offset does not exceed the latest possible offset
if offset > self.latest_offset {
return Err(anyhow!(
"truncate at {:?} but latest offset is {:?}",
offset,
self.latest_offset
));
}
if let AwaitingTruncate {
sealed_epoch,
next_epoch,
} = &self.epoch_progress
&& let TruncateOffset::Barrier { epoch } = offset
&& epoch == *sealed_epoch
{
let sealed_epoch = *sealed_epoch;
self.epoch_progress = Consuming(*next_epoch);
self.truncated_epoch_tx
.send(sealed_epoch)
.map_err(|_| anyhow!("unable to send sealed epoch"))?;View on GitHub (pinned to 6469eb736d)
Solutions
- Clamp the truncate offset to latest_offset before calling truncate
- Verify where the offset came from (checkpoint, watermark) for corruption or version skew
- Fix offset computation logic that predicts beyond written entries
Example fix
// before log_store.truncate(watermark).await?; // after log_store.truncate(watermark.min(latest_offset)).await?;
Defensive patterns
Strategy: validation
Validate before calling
fn sanitize_truncate_offset(offset: u64, latest_offset: u64) -> u64 {
offset.min(latest_offset)
} Try / catch
let safe = offset.min(latest_offset);
if safe > current_truncate_offset {
log_store.truncate(safe).await?;
} Prevention
- Clamp offsets against latest_offset before truncating
- Audit offset provenance (checkpoints, watermarks) for corruption
- Add unit tests for offset underflow/overflow paths
When it happens
Trigger: truncate(offset) invoked when offset > self.latest_offset, e.g. a consumer computing a future offset or using a stale/garbage offset value.
Common situations: Bugs in offset bookkeeping (u64 underflow/overflow), mismatched offset domains between log store versions, or corrupted checkpoint metadata supplying bad offsets.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- truncate offset {:?} but prev truncate offset is {:?}
- Filter can only receive bool array
- end of log stream
- unable to send sealed epoch
- should not call rewind on it
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/3c93eecbc44081e3.
Report an issue: GitHub.