risingwavelabs/risingwave · error · SinkError::Config
Either assume_role or access_key and secret_key must be…
Error message
Either assume_role or access_key and secret_key must be provided for Redshift COPY command
What it means
The Redshift `COPY` command that loads staged S3 files into Redshift needs AWS credentials: either an `assume_role` ARN or an `access_key`/`secret_key` pair. `build_copy_into_sql` throws this Config error when neither form of credentials is present in the sink config, because the generated COPY statement's authorization clause would be empty.
Solutions
- Add `aws.assume_role = 'arn:aws:iam::<account>:role/<role>'` to the sink WITH options.
- Or set both `aws.access_key` and `aws.secret_key` in the WITH options.
- Verify keys aren't empty strings and that the WITH options were actually passed to the sink (recreate the sink if needed).
Example fix
// before WITH (connector='redshift', aws.access_key='AKIA...', type='append-only'); // after WITH (connector='redshift', aws.access_key='AKIA...', aws.secret_key='...', type='append-only');
Defensive patterns
Strategy: validation
Validate before calling
fn has_copy_auth(p: &BTreeMap<String, String>) -> bool {
p.contains_key("aws.assume_role")
|| (p.contains_key("aws.access_key") && p.contains_key("aws.secret_key"))
} Prevention
- Prefer assume_role over static keys; set aws.assume_role at creation.
- Never supply access_key without secret_key (and vice versa).
When it happens
Trigger: Calling `copy_into_from_s3_to_redshift` when the sink config lacks `aws.assume_role` and also lacks both `aws.access_key` and `aws.secret_key` (one alone is insufficient).
Common situations: User configures IAM role auth but forgets `aws.assume_role`; provides only `aws.access_key` without `aws.secret_key`; empty-string keys parsed as None after validation.
Related errors
- Both `access_key` and `secret_key` must be provided
- Dont support auto create table for datatype
- gcs.service.account is required with Google Cloud Storage…
- intermediate.table.name is required for append-only sink
- intermediate.table.name is required for non-append-only sink
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/4e810a801c5a8b3b.
Report an issue: GitHub.
Appendix: source
Thrown at src/connector/src/sink/snowflake_redshift/redshift.rs:1010
fn build_copy_into_sql(
schema_name: Option<&str>,
table_name: &str,
manifest_dir: &str,
access_key: &Option<String>,
secret_key: &Option<String>,
assume_role: &Option<String>,
) -> Result<String> {
let table_name = build_full_table_name(schema_name, table_name);
let credentials = if let Some(assume_role) = assume_role {
&format!("aws_iam_role={}", assume_role)
} else if let (Some(access_key), Some(secret_key)) = (access_key, secret_key) {
&format!(
"aws_access_key_id={};aws_secret_access_key={}",
access_key, secret_key
)
} else {
return Err(SinkError::Config(anyhow!(
"Either assume_role or access_key and secret_key must be provided for Redshift COPY command"
)));
};
Ok(format!(
r#"
COPY {table_name}
FROM '{manifest_dir}'
CREDENTIALS '{credentials}'
FORMAT AS JSON 'auto'
DATEFORMAT 'auto'
TIMEFORMAT 'auto'
MANIFEST;
"#,
table_name = table_name,
manifest_dir = manifest_dir,
credentials = credentials
))
}View on GitHub (pinned to 6469eb736d)