risingwavelabs/risingwave · error · ConnectorError

Field '{field}' is not allowed to be altered on the fly for

Error message

Field '{field}' is not allowed to be altered on the fly for sink: {sink_name}

What it means

Thrown by `check_sink_allow_alter_on_fly_fields` in the connector crate when an ALTER on a sink includes a field that is not on the sink connector's registered allow-list for live alteration. Some sink properties (e.g. rate limits) can be changed without recreating the sink; everything else is rejected. If no allow-list is registered for the connector at all, a related error is raised instead.

Source

Thrown at src/connector/src/allow_alter_on_fly_fields.rs:543

    let allowed_fields = if sink_name == JdbcSink::SINK_NAME {
        CONNECTION_ALLOW_ALTER_ON_FLY_FIELDS.get(JdbcSink::SINK_NAME)
    } else {
        // Convert sink name to the type name key
        let Some(type_name) = sink_properties::sink_name_to_config_type_name(sink_name) else {
            return Err(ConnectorError::from(anyhow::anyhow!(
                "Unknown sink connector: {sink_name}"
            )));
        };
        SINK_ALLOW_ALTER_ON_FLY_FIELDS.get(type_name)
    };
    let Some(allowed_fields) = allowed_fields else {
        return Err(ConnectorError::from(anyhow::anyhow!(
            "No allow_alter_on_fly fields registered for sink: {sink_name}"
        )));
    };
    for field in fields {
        if !allowed_fields.contains(field) {
            return Err(ConnectorError::from(anyhow::anyhow!(
                "Field '{field}' is not allowed to be altered on the fly for sink: {sink_name}"
            )));
        }
    }
    Ok(())
}

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Remove the field from the ALTER statement and instead recreate the sink (DROP and CREATE) with the new value.
  2. Check the registered allow_alter_on_fly fields for your sink connector to see which fields are hot-alterable.
  3. Fix typos in the field name so it matches the registered allow-list exactly.

Example fix

// before
ALTER SINK my_sink SET (retention_ms = 86400000); -- not on allow-list
// after
DROP SINK my_sink;
CREATE SINK my_sink AS ... WITH (connector = 'kafka', retention_ms = 86400000);
Defensive patterns

Strategy: validation

Validate before calling

const ALLOWED_ALTER_FIELDS: Record<string, string[]> = { kafka: ['rate_limit'], ... };
function assertAlterable(sink: string, fields: string[]) {
  const allowed = ALLOWED_ALTER_FIELDS[sink] ?? [];
  const bad = fields.filter(f => !allowed.includes(f));
  if (bad.length) throw new Error(`Fields not hot-alterable for ${sink}: ${bad.join(',')}`);
}
assertAlterable('kafka', ['retention_ms']); // throws before ALTER

Try / catch

try { await alterSink(name, props); } catch (e) { if (String(e).includes('not allowed to be altered on the fly')) await recreateSink(name, props); else throw e; }

Prevention

When it happens

Trigger: Calling `validate_sink_props` or `update_connection_and_dependent_objects_props` with a props map containing a field that is not in the connector's `allowed_fields` set registered in allow_alter_on_fly_fields.rs.

Common situations: Running `ALTER SINK ... SET (field = value)` on a property that requires sink recreation, misspelling an alterable field name, or assuming a field is hot-alterable for a connector that only registers a few fields.

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/aa60ac76575d00a9. Report an issue: GitHub.