risingwavelabs/risingwave · critical

cannot find StreamActor of actor {}

Error message

cannot find StreamActor of actor {}

What it means

validate_database_info cross-checks each fragment actor against the provided stream_actors map. If an actor id present in the fragment's actor list is missing from stream_actors, recovery aborts. This detects a mismatch between fragment topology and the serialized actor table.

Source

Thrown at src/meta/src/barrier/mod.rs:177

        stream_actors: &HashMap<ActorId, StreamActor>,
        state_table_committed_epochs: &HashMap<TableId, u64>,
    ) -> MetaResult<()> {
        {
            for fragment in database_jobs.values().flat_map(|job| job.values()) {
                for (actor_id, actor) in &fragment.actors {
                    if !active_streaming_nodes
                        .current()
                        .contains_key(&actor.worker_id)
                    {
                        return Err(anyhow!(
                            "worker_id {} for actor {} does not exist",
                            actor.worker_id,
                            actor_id
                        )
                        .into());
                    }
                    if !stream_actors.contains_key(actor_id) {
                        return Err(anyhow!("cannot find StreamActor of actor {}", actor_id).into());
                    }
                }
                for state_table_id in &fragment.state_table_ids {
                    if !state_table_committed_epochs.contains_key(state_table_id) {
                        return Err(anyhow!(
                            "state table {} is not registered to hummock",
                            state_table_id
                        )
                        .into());
                    }
                }
            }
            for (job_id, fragments) in database_jobs {
                let mut committed_epochs =
                    InflightFragmentInfo::existing_table_ids(fragments.values()).map(|table_id| {
                        (
                            table_id,
                            *state_table_committed_epochs

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Re-run recovery after meta restart to rebuild consistent metadata from the durable snapshot
  2. Repair the job metadata so every fragment actor has a matching StreamActor record
  3. Drop and recreate the corrupted job if its metadata cannot be reconciled
  4. File a bug with the job/fragment ids; this indicates a metadata serialization bug
Defensive patterns

Strategy: validation

Validate before calling

let missing: Vec<_> = fragments.iter()
    .flat_map(|f| f.actors.keys())
    .filter(|id| !stream_actors.contains_key(*id))
    .collect();
if !missing.is_empty() { return Err(format!("actors missing from metadata: {:?}", missing)); }

Try / catch

if e.to_string().contains("cannot find StreamActor") {
    rebuild_job_metadata(job_id)?; // or drop/recreate the corrupted job
}

Prevention

When it happens

Trigger: Recovery-time validation where fragment.actors contains actor_id not present in the stream_actors map built from job metadata — inconsistent/duplicated metadata after failover or partial metadata update.

Common situations: Partial catalog updates during crashes; corrupted or desynchronized metadata snapshots; bugs in job rescheduling that drop actors.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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