{"record":{"id":"3f2a1e653357b47b","repo":"risingwavelabs/risingwave","slug":"no-active-frontend-nodes-found","errorCode":null,"errorMessage":"no active frontend nodes found","messagePattern":"no active frontend nodes found","errorType":"exception","errorClass":"MetaError","httpStatus":null,"severity":"error","filePath":"src/meta/service/src/ddl_service.rs","lineNumber":181,"sourceCode":"                metadata_manager: &MetadataManager,\n                ddl_controller: &DdlController,\n            ) -> MetaResult<()> {\n                let tables = metadata_manager\n                    .catalog_controller\n                    .list_unmigrated_tables()\n                    .await?;\n\n                if tables.is_empty() {\n                    tracing::info!(\"no legacy table fragments need migration\");\n                    return Ok(());\n                }\n\n                let client = {\n                    let workers = metadata_manager\n                        .list_worker_node(Some(WorkerType::Frontend), Some(State::Running))\n                        .await?;\n                    if workers.is_empty() {\n                        return Err(anyhow::anyhow!(\"no active frontend nodes found\").into());\n                    }\n                    let worker = workers.choose(&mut thread_rng()).unwrap();\n                    env.frontend_client_pool().get(worker).await?\n                };\n\n                for table in tables {\n                    let start = tokio::time::Instant::now();\n                    let req = GetTableReplacePlanRequest {\n                        database_id: table.database_id,\n                        table_id: table.id,\n                        cdc_table_change: None,\n                    };\n                    let resp = client\n                        .get_table_replace_plan(req)\n                        .await\n                        .context(\"failed to get table replace plan from frontend\")?;\n\n                    let plan = resp.into_inner().replace_plan.unwrap();","sourceCodeStart":163,"sourceCodeEnd":199,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/meta/service/src/ddl_service.rs#L163-L199","documentation":"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.","triggerScenarios":"Calling StartMigrateTableFragments while all Frontend worker nodes are registered but not in Running state, or no frontend has ever joined the cluster.","commonSituations":"Frontend crashed or was killed before the migration; cluster scaled to zero frontends; frontends stuck in Starting state due to failed heartbeats.","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."],"exampleFix":"// before: run migration with zero running frontends\n// after: ensure frontends are up\n$ ./risedev d   # or start frontend service\n$ ./risedev psql -c \"SHOW WORKERS;\"  # confirm Frontend / RUNNING\n# then retry the migration request","handlingStrategy":"retry","validationCode":"const workers = await listWorkers();\nif (!workers.some(w => w.type === 'Frontend' && w.state === 'Running')) {\n  throw new Error('Precheck: no running frontend nodes');\n}","typeGuard":"function hasRunningFrontend(ws) {\n  return ws.some(w => w.type === 'Frontend' && w.state === 'Running');\n}","tryCatchPattern":"try {\n  await client.startMigrateTableFragments(req);\n} catch (e) {\n  if (e.message.includes('no active frontend nodes')) {\n    await waitForRunningFrontend(); // poll cluster state\n    await client.startMigrateTableFragments(req); // retry\n  } else { throw e; }\n}","preventionTips":["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."],"tags":["cluster","frontend","migration","meta"],"backgroundTag":"empty-result-set","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}