risingwavelabs/risingwave · error · SinkError

s3.endpoint and s3.region need to be filled with at least on

Error message

s3.endpoint and s3.region need to be filled with at least one

What it means

After credential resolution, the AWS deltalake config builder requires that at least one of `s3.endpoint` or `s3.region` is set. Without either, the S3 object store location cannot be resolved, so the configuration is rejected with a Config error.

Source

Thrown at src/connector/src/sink/deltalake.rs:170

                    "s3.access.key and s3.secret.key is required with aws s3"
                ))
            })?
            .as_ref()
            .provide_credentials()
            .await
            .map_err(|e| SinkError::Config(e.into()))?;
        let region = sdk_config.region();
        let endpoint = sdk_config.endpoint_url();
        storage_options.insert(
            AWS_ACCESS_KEY_ID.to_owned(),
            credentials.access_key_id().to_owned(),
        );
        storage_options.insert(
            AWS_SECRET_ACCESS_KEY.to_owned(),
            credentials.secret_access_key().to_owned(),
        );
        if endpoint.is_none() && region.is_none() {
            return Err(SinkError::Config(anyhow!(
                "s3.endpoint and s3.region need to be filled with at least one"
            )));
        }
        storage_options.insert(
            AWS_REGION.to_owned(),
            region
                .map(|r| r.as_ref().to_owned())
                .unwrap_or_else(|| DEFAULT_REGION.to_owned()),
        );
        if let Some(s3_endpoint) = endpoint {
            storage_options.insert(AWS_ENDPOINT_URL.to_owned(), s3_endpoint.to_owned());
        }
        Ok(storage_options)
    }
}

enum DeltaTableUrl {
    S3(String),

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Set `s3.region` (e.g. 'us-east-1') for real AWS S3
  2. Set `s3.endpoint` (e.g. 'http://minio:9000') for S3-compatible storage
  3. Setting both is allowed and often needed for S3-compatible stores
  4. Double-check the option key spelling in the WITH clause

Example fix

// before
WITH ( connector='deltalake', location='s3://bucket/t', s3.access.key='k', s3.secret.key='s' )
// after
WITH ( connector='deltalake', location='s3://bucket/t', s3.access.key='k', s3.secret.key='s', s3.region='us-east-1' )
Defensive patterns

Strategy: validation

Validate before calling

fn validate_s3_location(props: &BTreeMap<String, String>) -> Result<(), String> {
    let has_endpoint = props.get("s3.endpoint").map_or(false, |v| !v.is_empty());
    let has_region = props.get("s3.region").map_or(false, |v| !v.is_empty());
    if !has_endpoint && !has_region {
        return Err("set s3.region (AWS) or s3.endpoint (S3-compatible)".into());
    }
    Ok(())
}

Prevention

When it happens

Trigger: `build_delta_lake_config_for_aws` finds `endpoint.is_none() && region.is_none()` when creating a DeltaLake sink against S3, i.e. neither `s3.endpoint` nor `s3.region` appears in the WITH options.

Common situations: Users forget `s3.region` for real AWS S3; users forget `s3.endpoint` for MinIO/other S3-compatible stores; region supplied under a misspelled option name.

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