risingwavelabs/risingwave · error

file_scan function is not supported in streaming mode

Error message

file_scan function is not supported in streaming mode

What it means

RisingWave's streaming engine cannot execute a file_scan (file source/function scan) node, so `ToStream for LogicalFileScan` deliberately returns an error via `bail!`. Unlike the EXCEPT stubs this is a clean, intended error: file scans are batch-only.

Source

Thrown at src/frontend/src/optimizer/plan_node/logical_file_scan.rs:168

        _ctx: &mut PredicatePushdownContext,
    ) -> PlanRef {
        // No pushdown.
        LogicalFilter::create(self.clone().into(), predicate)
    }
}

impl ToBatch for LogicalFileScan {
    fn to_batch(&self) -> Result<crate::optimizer::plan_node::BatchPlanRef> {
        Ok(BatchFileScan::new(self.core.clone()).into())
    }
}

impl ToStream for LogicalFileScan {
    fn to_stream(
        &self,
        _ctx: &mut ToStreamContext,
    ) -> Result<crate::optimizer::plan_node::StreamPlanRef> {
        bail!("file_scan function is not supported in streaming mode")
    }

    fn logical_rewrite_for_stream(
        &self,
        _ctx: &mut RewriteStreamContext,
    ) -> Result<(PlanRef, ColIndexMapping)> {
        bail!("file_scan function is not supported in streaming mode")
    }
}

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Keep file_scan usage in batch (ad-hoc) queries only.
  2. Ingest the file data into a table or a supported connector source (e.g. Kafka, Kinesis) and build the materialized view on that source instead.
  3. If streaming file ingestion is needed, load files via an external pipeline into a supported source first.

Example fix

-- before
CREATE MATERIALIZED VIEW mv AS SELECT * FROM file_scan('s3://bucket/data.parquet');

-- after
CREATE SOURCE s (...) WITH (connector = 'kafka', ...);
CREATE MATERIALIZED VIEW mv AS SELECT * FROM s;
Defensive patterns

Strategy: try-catch

Validate before calling

-- reject streaming DDL that reads files directly
if ddl.is_streaming() && ddl.references_file_scan() {
    return Err("file_scan is batch-only; use a connector source".into());
}

Type guard

fn is_streamable(node: &dyn PlanTreeNode) -> bool {
    node.node_type() != PlanNodeType::LogicalFileScan
}

Try / catch

match to_stream(plan) {
    Err(e) if e.to_string().contains("file_scan") =>
        advise("use Kafka/Kinesis source or a table for streaming"),
    r => r,
}

Prevention

When it happens

Trigger: Attempting to create a materialized view, or any streaming/continuous query, whose plan contains a LogicalFileScan node (a query reading from a file via file_scan function).

Common situations: Users try to `CREATE MATERIALIZED VIEW` over a file-based source; or run `CREATE TABLE ... FROM file` style flows expecting incremental streaming from files.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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