risingwavelabs/risingwave · error
unable to send sealed epoch
Error message
unable to send sealed epoch
What it means
While truncating an epoch, the in-memory log store tried to notify the sealed-epoch watcher via a broadcast channel but all receivers were dropped, so the send failed. This indicates the sealed-epoch consumer side is gone.
Source
Thrown at src/stream/src/common/log_store_impl/in_mem.rs:262
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"))?;
}
self.truncate_offset = offset;
Ok(())
}
async fn rewind(&mut self) -> LogStoreResult<()> {
Err(anyhow!("should not call rewind on it"))
}
async fn start_from(&mut self, _start_offset: Option<u64>) -> LogStoreResult<()> {
Ok(())
}
}
impl LogWriter for BoundedInMemLogStoreWriter {
async fn init(
&mut self,
epoch: EpochPair,View on GitHub (pinned to 6469eb736d)
Solutions
- Check the receiver task for panics or early termination in logs
- Ensure the sealed-epoch consumer is spawned and alive before truncation happens
- Fix shutdown ordering so the log store is not truncating after consumers exit
Defensive patterns
Strategy: try-catch
Try / catch
match log_store.truncate(offset).await {
Err(e) if e.to_string().contains("unable to send sealed epoch") => {
tracing::warn!("sealed-epoch receiver gone; check consumer task");
// restart consumer or surface shutdown
}
other => other?,
} Prevention
- Keep the sealed-epoch receiver task alive across the log store's lifetime
- Order shutdown: stop truncation before dropping consumers
- Watch consumer task panics in monitoring
When it happens
Trigger: truncate moves epoch progress past a sealed epoch and calls truncated_epoch_tx.send(sealed_epoch) when no receiver is alive.
Common situations: The sealed-epoch reader task panicked or was dropped before truncation, shutdown races between the log store and its consumers, or incorrect initialization dropping the receiver.
Related errors
- end of log stream
- truncate offset {:?} but prev truncate offset is {:?}
- truncate at {:?} but latest offset is {:?}
- should not call rewind on it
- Filter can only receive bool array
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/809ef9bb4fb93802.
Report an issue: GitHub.