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
- Keep file_scan usage in batch (ad-hoc) queries only.
- 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.
- 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
- Use file_scan only for one-off batch reads
- Ingest files into tables or connector sources for streaming workloads
- Document batch-only operators for SQL users
- Add early DDL validation for unsupported streaming sources
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
- Iceberg metadata relations are not supported in streaming qu
- next offset {:?} should be later than current offset {:?}
- new item epoch {} does not match current chunk offset epoch
- new item epoch {} does not exceed barrier offset epoch {}
- BatchPosixFsReader should not be used
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/a2fee74361353881.
Report an issue: GitHub.