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
- Start at least one frontend node and wait until it registers as Running (check via Meta dashboard or `show workers`).
- Check frontend logs for heartbeat failures that keep them out of Running state, then restart the migration.
- Verify network connectivity between frontends and the meta node on the configured ports.
- 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
- Ensure at least one healthy frontend before running fragment migrations.
- Monitor frontend heartbeat state and alert when zero frontends are Running.
- Gate migration jobs on cluster-health prechecks in automation.
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
- no frontend worker available
- Pin snapshot error: {0} fails to get epoch {1}
- no active streaming workers for reschedule
- Dropping sink into table is not allowed for unmigrated table
- invalid parallelism
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/3f2a1e653357b47b.
Report an issue: GitHub.