risingwavelabs/risingwave · error · MetaError

no active frontend nodes found

Error message

no active frontend nodes found

What it means

migrate_inner in src/meta/service/src/ddl_service.rs:181 returns this error when listing frontend worker nodes with State::Running yields an empty list during a table-fragment migration. The migration needs a randomly chosen running frontend node to forward the operation through, and none is available.

Source

Thrown at src/meta/service/src/ddl_service.rs:181

                metadata_manager: &MetadataManager,
                ddl_controller: &DdlController,
            ) -> MetaResult<()> {
                let tables = metadata_manager
                    .catalog_controller
                    .list_unmigrated_tables()
                    .await?;

                if tables.is_empty() {
                    tracing::info!("no legacy table fragments need migration");
                    return Ok(());
                }

                let client = {
                    let workers = metadata_manager
                        .list_worker_node(Some(WorkerType::Frontend), Some(State::Running))
                        .await?;
                    if workers.is_empty() {
                        return Err(anyhow::anyhow!("no active frontend nodes found").into());
                    }
                    let worker = workers.choose(&mut thread_rng()).unwrap();
                    env.frontend_client_pool().get(worker).await?
                };

                for table in tables {
                    let start = tokio::time::Instant::now();
                    let req = GetTableReplacePlanRequest {
                        database_id: table.database_id,
                        table_id: table.id,
                        cdc_table_change: None,
                    };
                    let resp = client
                        .get_table_replace_plan(req)
                        .await
                        .context("failed to get table replace plan from frontend")?;

                    let plan = resp.into_inner().replace_plan.unwrap();

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Start at least one frontend node and wait until it registers as Running (check via Meta dashboard or `show workers`).
  2. Check frontend logs for heartbeat failures that keep them out of Running state, then restart the migration.
  3. Verify network connectivity between frontends and the meta node on the configured ports.
  4. Re-issue the migrate table fragments request once a running frontend is available.

Example fix

// before: run migration with zero running frontends
// after: ensure frontends are up
$ ./risedev d   # or start frontend service
$ ./risedev psql -c "SHOW WORKERS;"  # confirm Frontend / RUNNING
# then retry the migration request
Defensive patterns

Strategy: retry

Validate before calling

const workers = await listWorkers();
if (!workers.some(w => w.type === 'Frontend' && w.state === 'Running')) {
  throw new Error('Precheck: no running frontend nodes');
}

Type guard

function hasRunningFrontend(ws) {
  return ws.some(w => w.type === 'Frontend' && w.state === 'Running');
}

Try / catch

try {
  await client.startMigrateTableFragments(req);
} catch (e) {
  if (e.message.includes('no active frontend nodes')) {
    await waitForRunningFrontend(); // poll cluster state
    await client.startMigrateTableFragments(req); // retry
  } else { throw e; }
}

Prevention

When it happens

Trigger: Calling StartMigrateTableFragments while all Frontend worker nodes are registered but not in Running state, or no frontend has ever joined the cluster.

Common situations: Frontend crashed or was killed before the migration; cluster scaled to zero frontends; frontends stuck in Starting state due to failed heartbeats.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


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