risingwavelabs/risingwave · error

no upstream actors found from fragment

Error message

no upstream actors found from fragment {} to upstream source fragment {}

What it means

resolve_backfill_splits builds the upstream actor set for a source backfill fragment from the `actor_no_shuffle` mapping; this error fires when the (upstream_fragment -> fragment) entry has no actor map. A one-on-one no-shuffle mapping is mandatory for source backfill topologies.

Solutions

  1. Check the upstream fragment uses no_shuffle dispatch to the backfill fragment
  2. Recreate the source/backfill so the plan is regenerated with the expected topology
  3. Inspect actor_no_shuffle in meta logs to see which edge is missing
  4. Report/upgrade if the planner produced a non-no-shuffle edge for source backfill
Defensive patterns

Strategy: validation

Validate before calling

// before resolving backfill splits, confirm the upstream fragment has no_shuffle dispatchers
assert!(actor_no_shuffle.contains_key(&upstream_source_fragment_id));

Try / catch

if let Err(e) = resolve_backfill_splits(...) {
    tracing::error!("backfill topology invalid: {e}");
    // recreate the MV/source instead of retrying
}

Prevention

When it happens

Trigger: Calling resolve_backfill_splits (during source backfill split resolution/migration) when the upstream source fragment lacks a no_shuffle actor mapping to the backfill fragment, e.g. the upstream dispatches with a non-no_shuffle dispatcher.

Common situations: Source backfill created against an upstream plan that does not guarantee 1:1 no-shuffle distribution; topology changes after MV rebuild; version mismatch between frontend planner and meta assumptions.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at src/meta/src/stream/source_manager/split_assignment.rs:288

    /// with its upstream source fragment using the `new_no_shuffle` actor mapping and
    /// the existing split assignment looked up via the provided closure.
    pub fn resolve_backfill_splits(
        table_fragments: &StreamJobFragments,
        actor_no_shuffle: &ActorNewNoShuffle,
        get_upstream_actor_splits: impl Fn(FragmentId, ActorId) -> Option<Vec<SplitImpl>>,
    ) -> MetaResult<SplitAssignment> {
        let source_backfill_fragments = table_fragments.source_backfill_fragments();

        let mut assigned = HashMap::new();

        for (_source_id, fragments) in source_backfill_fragments {
            for (fragment_id, upstream_source_fragment_id) in fragments {
                // Get upstream actors from actor_no_shuffle mapping
                let upstream_actors: HashSet<ActorId> = actor_no_shuffle
                    .get(&upstream_source_fragment_id)
                    .and_then(|m| m.get(&fragment_id))
                    .ok_or_else(|| {
                        anyhow!(
                            "no upstream actors found from fragment {} to upstream source fragment {}",
                            fragment_id,
                            upstream_source_fragment_id
                        )
                    })?.keys().copied().collect();

                let mut backfill_actors = vec![];
                let Some(source_new_no_shuffle) = actor_no_shuffle
                    .get(&upstream_source_fragment_id)
                    .and_then(|source_upstream_actor_no_shuffle| {
                        source_upstream_actor_no_shuffle.get(&fragment_id)
                    })
                else {
                    return Err(anyhow::anyhow!(
                            "source backfill fragment's upstream fragment should have one-on-one no_shuffle mapping, fragment_id: {fragment_id}, upstream_fragment_id: {upstream_source_fragment_id}, actor_no_shuffle: {actor_no_shuffle:?}",
                            fragment_id = fragment_id,
                            upstream_source_fragment_id = upstream_source_fragment_id,
                            actor_no_shuffle = actor_no_shuffle,

View on GitHub (pinned to 6469eb736d)