risingwavelabs/risingwave · error
replace sink into table is not supported
Error message
replace sink into table is not supported
What it means
Guard in create_job_catalog during sink replacement (`ALTER ... REPLACE`): the object being replaced is configured as a sink-into-table replacement, which the meta service does not support, so job catalog creation for the replacement fails.
Source
Thrown at src/meta/src/controller/streaming_job.rs:528
.and_then(|(sink, object)| object.map(|object| (sink, object)))
.ok_or_else(|| MetaError::catalog_id_not_found("sink", *old_sink_id))?;
let old_streaming_job = StreamingJobModel::find_by_id(old_sink_id.as_job_id())
.one(&txn)
.await?
.ok_or_else(|| MetaError::catalog_id_not_found("sink", *old_sink_id))?;
if old_object.obj_type != ObjectType::Sink
|| old_object.database_id != Some(sink.database_id)
|| old_object.schema_id != Some(sink.schema_id)
|| old_sink.name != sink.name
{
bail!(
"old sink {} does not match replacement sink {}",
old_sink_id,
sink.name
);
}
if old_sink.target_table.is_some() || sink.target_table.is_some() {
bail!("replace sink into table is not supported");
}
if old_streaming_job.job_status != JobStatus::Created {
bail!("sink {} is not ready to be replaced", old_sink_id);
}
} else {
check_relation_name_duplicate(
&streaming_job.name(),
streaming_job.database_id(),
streaming_job.schema_id(),
&txn,
)
.await?;
}
// check if any dependency is in altering status.
if !dependencies.is_empty() {
let altering_cnt = ObjectDependency::find()
.join(View on GitHub (pinned to 6469eb736d)
Solutions
- Drop the sink-into-table sink and create the new sink separately instead of using REPLACE.
- Ensure both old and new sinks are external (non-table-target) sinks when using replace.
- Split the operation: drop old sink, then CREATE SINK INTO TABLE if that is the goal.
Defensive patterns
Strategy: validation
Validate before calling
-- check the old sink is not sink-into-table SELECT s.target_table IS NOT NULL AS into_table FROM rw_sinks s WHERE s.id = <old_sink_id>;
Try / catch
if let Err(e) = catalog.create_job_catalog(job).await {
if e.to_string().contains("replace sink into table is not supported") {
// fall back to DROP SINK + CREATE SINK
}
} Prevention
- Never use REPLACE for sinks created with INTO table
- Document replace-support limits in DDL tooling
When it happens
Trigger: create_job_catalog with replace_sink where old_sink.target_table is Some or the new sink's target_table is Some.
Common situations: User attempts CREATE SINK ... REPLACE on a sink created with `INTO table`, or replaces a plain sink with a sink-into-table sink.
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
- old sink {} does not match replacement sink {}
- sink {} is not ready to be replaced
- object {} is not a sink
- replace sink must not use snapshot backfill
- old sink job {} not found in barrier state
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/ccb998134961a1d7.
Report an issue: GitHub.