risingwavelabs/risingwave · error

ALTER SOURCE_RATE_LIMIT is not for table without source

Error message

ALTER SOURCE_RATE_LIMIT is not for table without source

What it means

`ALTER TABLE ... SOURCE_RATE_LIMIT` throttles the ingestion source associated with a table. When the target table is a plain table (e.g. a dml-target or regular table) with no associated source (associated_source_id is None), there is no source to throttle, so the handler bails. Only tables created from a connector (WITH a source / created via CREATE TABLE ... FROM ...) have an associated source.

Solutions

  1. Use `ALTER TABLE t DML_RATE_LIMIT ...` to throttle writes to a source-less table.
  2. Only apply SOURCE_RATE_LIMIT to tables created from an external source (e.g. Kafka/CDC-backed tables with an associated source).
  3. Create the table with a backing source if source-side throttling is actually the goal.

Example fix

// before
ALTER TABLE plain_table SOURCE_RATE_LIMIT 100;
// after
ALTER TABLE plain_table DML_RATE_LIMIT 100;
-- or, for a connector-backed table:
ALTER TABLE kafka_backed_table SOURCE_RATE_LIMIT 100;
Defensive patterns

Strategy: validation

Validate before calling

-- Only apply SOURCE_RATE_LIMIT to tables backed by a source:
SELECT t.name, s.id AS source_id
FROM rw_catalog.rw_tables t
LEFT JOIN rw_catalog.rw_sources s ON t.associated_source_id = s.id
WHERE t.name = 'my_table' AND t.table_type = 'table';
-- If source_id IS NULL, use DML_RATE_LIMIT instead.

Prevention

When it happens

Trigger: Running `ALTER TABLE t SOURCE_RATE_LIMIT ...` where t exists and is a TABLE, but t.associated_source_id is None — i.e. a native RisingWave table not backed by an external source.

Common situations: Confusing DML rate limit (throttle_type=Dml, which works on any table) with the source rate limit (throttle_type=Source, which requires a connector-backed table); applying a source limit to a table populated only by DML/INSERT.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at src/frontend/src/handler/alter_streaming_rate_limit.rs:96

            let (source, schema_name) =
                reader.get_source_by_name(db_name, schema_path, &real_table_name)?;
            session.check_privilege_for_drop_alter(schema_name, &**source)?;
            (StatementType::ALTER_SOURCE, source.id.as_raw_id())
        }
        (PbThrottleTarget::Table, PbThrottleType::Dml) => {
            let reader = session.env().catalog_reader().read_guard();
            let table =
                check_table_mismatch(&reader, &session, db_name, schema_path, &real_table_name)?;
            (StatementType::ALTER_TABLE, table.id.as_raw_id())
        }
        (PbThrottleTarget::Table, PbThrottleType::Source) => {
            let reader = session.env().catalog_reader().read_guard();
            let table =
                check_table_mismatch(&reader, &session, db_name, schema_path, &real_table_name)?;
            let source_id = if let Some(id) = table.associated_source_id {
                id.as_raw_id()
            } else {
                bail!("ALTER SOURCE_RATE_LIMIT is not for table without source")
            };
            (StatementType::ALTER_TABLE, source_id)
        }
        (PbThrottleTarget::Table, PbThrottleType::Backfill) => {
            let reader = session.env().catalog_reader().read_guard();
            let table =
                check_table_mismatch(&reader, &session, db_name, schema_path, &real_table_name)?;
            if table.cdc_table_type.is_none() {
                return Err(ErrorCode::InvalidInputSyntax(format!(
                    "\"{table_name}\" is not a CDC table",
                ))
                .into());
            }
            (StatementType::ALTER_TABLE, table.id.as_raw_id())
        }
        (PbThrottleTarget::Sink, PbThrottleType::Sink) => {
            let reader = session.env().catalog_reader().read_guard();
            let (sink, schema_name) =

View on GitHub (pinned to 6469eb736d)