risingwavelabs/risingwave · error · SinkError::Config

`task.serverless` must not be combined with `warehouse`

Error message

`task.serverless` must not be combined with `warehouse`

What it means

Serverless Snowflake tasks cannot specify a warehouse, since Snowflake allocates compute automatically. from_btreemap rejects combining `task.serverless = true` with a `warehouse` option to surface the incompatibility at sink creation.

Solutions

  1. Remove the `warehouse` option from the WITH clause
  2. Or remove `task.serverless = true` if you specifically need to run on a named warehouse

Example fix

// before
WITH (connector='snowflake', type='upsert', with_s3=true, task.serverless=true, warehouse='COMPUTE_WH');
// after
WITH (connector='snowflake', type='upsert', with_s3=true, task.serverless=true);
Defensive patterns

Strategy: validation

Validate before calling

if options.get("task.serverless").map(|v| v.as_str()) == Some("true") && options.contains_key("warehouse") {
    return Err("task.serverless conflicts with warehouse");
}

Prevention

When it happens

Trigger: Creating a Snowflake upsert sink with both `task.serverless = true` and `warehouse = ...` in the WITH options.

Common situations: Template sink DDL that includes a warehouse, then enabling task.serverless for cost savings without removing the warehouse; migrating an existing warehouse-task config to serverless.

Related errors


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

Appendix: source

Thrown at src/connector/src/sink/snowflake_redshift/snowflake.rs:266

            || properties.contains_key("write.target.interval.seconds")
            || config.snowflake_warehouse.is_some()
            || config.task_serverless
            || config.task_target_completion_interval.is_some();
        if config.r#type != SINK_TYPE_UPSERT && has_upsert_task_config {
            return Err(SinkError::Config(anyhow!(
                "`intermediate.table.name`, `write.target.interval.seconds`, `warehouse`, \
                 `task.serverless`, and `task.target_completion_interval` require `{}` = {}",
                SINK_TYPE_OPTION,
                SINK_TYPE_UPSERT
            )));
        }
        if config.task_target_completion_interval.is_some() && !config.task_serverless {
            return Err(SinkError::Config(anyhow!(
                "`task.target_completion_interval` requires `task.serverless` to be true"
            )));
        }
        if config.task_serverless && config.snowflake_warehouse.is_some() {
            return Err(SinkError::Config(anyhow!(
                "`task.serverless` must not be combined with `warehouse`"
            )));
        }

        // Normalize and validate authentication method
        let has_password = config.password.is_some();
        let has_file = config.private_key_file.is_some();
        let has_pem = config.private_key_pem.as_deref().is_some();

        let normalized_auth_method = match config
            .auth_method
            .as_deref()
            .map(|s| s.trim().to_ascii_lowercase())
        {
            Some(method) if method == AUTH_METHOD_PASSWORD => {
                if !has_password {
                    return Err(SinkError::Config(anyhow!(
                        "auth.method=password requires `password`"

View on GitHub (pinned to 6469eb736d)