risingwavelabs/risingwave · error · ConnectorError

Unknown sink connector: {sink_name}

Error message

Unknown sink connector: {sink_name}

What it means

check_sink_allow_alter_on_fly_fields could not map sink_name to a registered sink configuration type, so no allow_alter_on_fly allowlist exists. The sink connector name is unrecognized for on-the-fly field alteration (note: JDBC sinks are special-cased via CONNECTION_ALLOW_ALTER_ON_FLY_FIELDS).

Source

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

}

/// Checks if all given fields are allowed to be altered on the fly for the specified sink connector.
/// Returns Ok(()) if all fields are allowed, otherwise returns a `ConnectorError`.
pub fn check_sink_allow_alter_on_fly_fields(
    sink_name: &str,
    fields: &[String],
) -> crate::error::ConnectorResult<()> {
    // TODO(#24846): JDBC sink currently uses `()` as sink config type in `for_all_sinks!`,
    // so it cannot have an isolated key in `SINK_ALLOW_ALTER_ON_FLY_FIELDS`.
    // Reuse the JDBC entry in `CONNECTION_ALLOW_ALTER_ON_FLY_FIELDS` for now.
    // TODO(#24846): remove this special case after JDBC sink has a dedicated config type
    // and allow-alter fields are generated directly into `SINK_ALLOW_ALTER_ON_FLY_FIELDS`.
    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. Correct the sink connector name spelling in the WITH clause
  2. Verify supported sink connectors for your RW version
  3. Ensure the sink type is compiled/registered (check build features or enterprise edition)

Example fix

// before
CREATE SINK sk FROM t WITH (connector = 'redis_s', ...);
// after
CREATE SINK sk FROM t WITH (connector = 'redis', ...);
Defensive patterns

Strategy: validation

Validate before calling

const KNOWN_SINKS: &[&str] = &["kafka","iceberg","jdbc","redis","deltalake" /*...*/];
if !KNOWN_SINKS.contains(&sink_name) {
    return Err(format!("unknown sink connector: {sink_name}"));
}

Try / catch

match res {
    Err(e) if e.to_string().starts_with("Unknown sink connector") => {
        // show list of valid sink connectors to the user
    }
    other => other?,
}

Prevention

When it happens

Trigger: ALTER SINK (alter on the fly) where the sink's connector name fails sink_name_to_config_type_name: typo, unsupported sink, or a sink removed in this build.

Common situations: Typos like connector='deltlake' instead of 'deltalake'; using a sink not available in the deployment (e.g. enterprise-only); upgrading RW and connector names changing.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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