risingwavelabs/risingwave · error · SinkError::Config

username is required

Error message

username is required

What it means

Alongside `jdbc.url`, `build_jdbc_connection_properties` requires a `username` to set the `user` JDBC connection property. When `config.username` is `None`, this Config error is thrown while building the Snowflake JDBC client.

Source

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

fn default_with_s3() -> bool {
    true
}

impl SnowflakeV2Config {
    /// Build JDBC Properties for the Snowflake JDBC connection (no URL parameters).
    /// Returns (`jdbc_url`, `driver_properties`).
    /// - `driver_properties` are transformed/used by the Java runner and passed to `DriverManager::getConnection(url, props)`
    ///
    /// Note: This method assumes the config has been validated by `from_btreemap`.
    pub fn build_jdbc_connection_properties(&self) -> Result<(String, Vec<(String, String)>)> {
        let jdbc_url = self
            .jdbc_url
            .clone()
            .ok_or(SinkError::Config(anyhow!("jdbc.url is required")))?;
        let username = self
            .username
            .clone()
            .ok_or(SinkError::Config(anyhow!("username is required")))?;

        let mut connection_properties: Vec<(String, String)> = vec![("user".to_owned(), username)];

        // auth_method is guaranteed to be Some after validation in from_btreemap
        match self.auth_method.as_deref().unwrap() {
            AUTH_METHOD_PASSWORD => {
                // password is guaranteed to exist by from_btreemap validation
                connection_properties.push(("password".to_owned(), self.password.clone().unwrap()));
            }
            AUTH_METHOD_KEY_PAIR_FILE => {
                // private_key_file is guaranteed to exist by from_btreemap validation
                connection_properties.push((
                    "private_key_file".to_owned(),
                    self.private_key_file.clone().unwrap(),
                ));
                if let Some(pwd) = self.private_key_file_pwd.clone() {
                    connection_properties.push(("private_key_file_pwd".to_owned(), pwd));
                }

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Add `snowflake.username = '<user>'` to the sink WITH options and recreate the sink.
  2. Double-check the exact option name (`snowflake.username`) matches the connector version.
  3. Run config validation (`from_btreemap`) upfront to surface all missing fields at once.

Example fix

// before
WITH (connector='snowflake', snowflake.jdbc.url='jdbc:snowflake://...');
// after
WITH (connector='snowflake', snowflake.jdbc.url='jdbc:snowflake://...', snowflake.username='my_user');
Defensive patterns

Strategy: validation

Validate before calling

if !props.contains_key("snowflake.username") {
    return Err(anyhow!("snowflake.username is required"));
}

Prevention

When it happens

Trigger: Calling `build_jdbc_connection_properties` (via `build_snowflake_task_ctx_jdbc_client`) with a config where `username` is None, i.e. `snowflake.username` was missing from the sink's WITH options.

Common situations: Snowflake sink created without the username option; username supplied under a wrong key name; key-based auth configured but username still required and omitted.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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