risingwavelabs/risingwave · error

since_timestamp is not before the committed epoch of upstrea

Error message

since_timestamp is not before the committed epoch of upstream table {}: requested epoch {}, committed epoch {}

What it means

The requested since_timestamp is at or after the upstream table's committed epoch, meaning there is no committed history strictly before the requested point to snapshot against. The since epoch must fall strictly between the first retained checkpoint and the committed epoch.

Source

Thrown at src/meta/src/barrier/context/context_impl.rs:87

    let Some(first_log) = change_log.first() else {
        return Err(anyhow::anyhow!(
            "empty table changelog found for upstream table {} when resolving since_timestamp",
            table_id
        )
        .into());
    };
    let first_checkpoint_epoch = first_log.checkpoint_epoch;
    if since_epoch < first_checkpoint_epoch {
        return Err(anyhow::anyhow!(
            "since_timestamp is earlier than the retained changelog of upstream table {}: requested epoch {}, first retained checkpoint epoch {}",
            table_id,
            since_epoch,
            first_checkpoint_epoch,
        )
        .into());
    }
    if since_epoch >= upstream_committed_epoch {
        return Err(anyhow::anyhow!(
            "since_timestamp is not before the committed epoch of upstream table {}: requested epoch {}, committed epoch {}",
            table_id,
            since_epoch,
            upstream_committed_epoch,
        )
        .into());
    }
    let latest_log = change_log.last().expect("checked non-empty");
    if upstream_committed_epoch != latest_log.checkpoint_epoch {
        return Err(anyhow::anyhow!(
            "upstream committed epoch {} does not match latest changelog epoch {} for upstream table {}",
            upstream_committed_epoch,
            latest_log.checkpoint_epoch,
            table_id,
        )
        .into());
    }

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Supply a since_timestamp earlier than the upstream table's latest committed epoch
  2. Fix timestamp conversion/timezone so the epoch is in the correct range
  3. Retry with a slightly earlier since_timestamp

Example fix

-- before
SINCE_TIMESTAMP = now();
-- after
SINCE_TIMESTAMP = now() - interval '1 minute';
Defensive patterns

Strategy: validation

Validate before calling

if since_epoch >= upstream_committed_epoch {
    return Err("since_timestamp must be strictly before the upstream committed epoch");
}

Type guard

fn strictly_before_committed(since: u64, committed: u64) -> bool { since < committed }

Try / catch

match create_snapshot_backfill(...).await {
    Err(e) if e.contains("not before the committed epoch") => use_earlier_timestamp(),
    other => other,
}

Prevention

When it happens

Trigger: resolve_since_timestamp_log_store_epoch with since_epoch >= upstream_committed_epoch — e.g. a since timestamp computed after the upstream table's latest commit.

Common situations: Clock skew or wrong timestamp conversion (future timestamp supplied); upstream table already fully committed before backfill creation; passing 'now' while committed epoch is derived from a later barrier.

Related errors


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/3568bbe8e177ace8. Report an issue: GitHub.