risingwavelabs/risingwave · error
No stream cdc scan node found in stream scan fragment
Error message
No stream cdc scan node found in stream scan fragment
What it means
validate_cdc_table walks the stream scan fragment looking for a StreamCdcScan node and fails if none is found. This means the plan generated for a CDC table lacks the required CDC scan operator, so meta refuses to create the streaming job rather than build a table that cannot consume CDC events.
Solutions
- Verify frontend and meta are the same version and rebuild/redeploy consistently.
- Check the generated plan (EXPLAIN or fragment view) to confirm whether a cdc scan exists upstream; fix the source/connector definition.
- If triggered by a code change, extend or correct the plan so the CDC table includes a StreamCdcScan node.
Example fix
// before: validating an arbitrary scan fragment without a cdc scan node // after: ensure the table is created with a proper CDC source so the plan contains StreamCdcScan CREATE TABLE t (...) WITH ( connector = 'cdc-postgres', ... ) FROM pg_source;
Defensive patterns
Strategy: try-catch
Try / catch
if let Err(e) = create_cdc_table(...).await {
if e.to_string().contains("No stream cdc scan node found") {
// check source is a proper CDC source and versions match
}
} Prevention
- Create CDC tables only from proper CDC sources/connector definitions
- Pin consistent frontend/meta versions
- Use EXPLAIN/fragment view to verify cdc scan presence when debugging
When it happens
Trigger: Creating a CDC table where the stream scan fragment contains no StreamCdcScan node — e.g. the frontend produced a wrong plan for the CDC source, or validation is applied to a fragment type that never contains a cdc scan.
Common situations: Bugs in CDC plan generation after frontend changes; applying a CDC table on a source that got rewritten to a different operator; version mismatch between frontend and meta binaries.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- invalid backfill_num_rows_per_split, must be greater than 0
- PostgreSQL schema ` ` does not exist
- PostgreSQL table ` `.` ` does not exist
- source validation failed
- The database name ' ' in FROM clause does not match the…
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/65d93a0e9dce938a.
Report an issue: GitHub.
Appendix: source
Thrown at src/meta/src/rpc/ddl_controller.rs:1053
}
// When there's generated columns, the cdc scan node is wrapped in a project node
Some(NodeBody::Project(_)) => {
for input in &stream_scan_fragment.nodes.input {
assert_parallelism(stream_scan_fragment.distribution_type, &input.node_body);
if self
.validate_cdc_table_inner(&input.node_body, table.id)
.await?
{
found_cdc_scan = true;
}
}
}
_ => {
bail!("Unexpected node body for stream cdc scan");
}
};
if !found_cdc_scan {
bail!("No stream cdc scan node found in stream scan fragment");
}
Ok(())
}
async fn validate_cdc_table_inner(
&self,
node_body: &Option<NodeBody>,
table_id: TableId,
) -> MetaResult<bool> {
if let Some(NodeBody::StreamCdcScan(stream_cdc_scan)) = node_body
&& let Some(ref cdc_table_desc) = stream_cdc_scan.cdc_table_desc
{
let options_with_secret = WithOptionsSecResolved::new(
cdc_table_desc.connect_properties.clone(),
cdc_table_desc.secret_refs.clone(),
);
let mut props = ConnectorProperties::extract(options_with_secret, true)?;View on GitHub (pinned to 6469eb736d)