risingwavelabs/risingwave · error · ConnectorError
Both `access_key` and `secret_key` must be provided
Error message
Both `access_key` and `secret_key` must be provided
What it means
Thrown by `build_credential_provider` in connector_common/common.rs when static AWS credentials are expected but only one of `access_key`/`secret_key` is set, default credential providers are disabled (RW_DISABLE_DEFAULT_CREDENTIAL env true), and no complete static pair is available. The AWS SDK requires both parts of a static credential pair.
Source
Thrown at src/connector/src/connector_common/common.rs:159
}
async fn build_credential_provider(&self) -> ConnectorResult<SharedCredentialsProvider> {
if let (Some(access_key), Some(secret_key)) =
(self.access_key.as_ref(), self.secret_key.as_ref())
{
Ok(SharedCredentialsProvider::new(
aws_credential_types::Credentials::from_keys(
access_key,
secret_key,
self.session_token.clone(),
),
))
} else if !env_var_is_true(DISABLE_DEFAULT_CREDENTIAL) {
Ok(SharedCredentialsProvider::new(
aws_config::default_provider::credentials::default_provider().await,
))
} else {
bail!("Both `access_key` and `secret_key` must be provided")
}
}
async fn with_role_provider(
&self,
credential: SharedCredentialsProvider,
) -> ConnectorResult<SharedCredentialsProvider> {
if let Some(role_name) = &self.arn {
let region = self.build_region().await?;
let mut role = AssumeRoleProvider::builder(role_name)
.session_name("RisingWave")
.region(region);
if let Some(id) = &self.external_id {
role = role.external_id(id);
}
let provider = role.build_from_provider(credential).await;
Ok(SharedCredentialsProvider::new(provider))
} else {View on GitHub (pinned to 6469eb736d)
Solutions
- Provide both `access_key` and `secret_key` in the connector's secret/props.
- If you intend to use the environment/instance-role credential chain, do not disable default credentials (leave RW_DISABLE_DEFAULT_CREDENTIAL unset/false) and remove the partial static keys.
- Check the mounted secret/parameters store entry actually contains both fields.
Example fix
// before
props: { access_key: "AKIA..." } // secret_key missing
// after
props: { access_key: "AKIA...", secret_key: "..." } Defensive patterns
Strategy: validation
Validate before calling
function validateAwsStaticCreds(props) {
const hasAk = !!props.access_key, hasSk = !!props.secret_key;
if (hasAk !== hasSk) throw new Error('access_key and secret_key must both be set (or both omitted)');
}
validateAwsStaticCreds(withProps); Type guard
const hasPair = (p) => typeof p.access_key === 'string' && p.access_key.length > 0 && typeof p.secret_key === 'string' && p.secret_key.length > 0;
Try / catch
try { await createSink(cfg); } catch (e) { if (String(e).includes('Both `access_key` and `secret_key`')) { fixSecrets(cfg); return createSink(cfg); } throw e; } Prevention
- Store access_key and secret_key together in one secret/parameter-set so they deploy atomically.
- Never set one half of the pair; use the default credential chain if you have neither.
- Check RW_DISABLE_DEFAULT_CREDENTIAL before relying on instance roles.
When it happens
Trigger: Building an AWS config for a sink/source with `access_key` set but `secret_key` missing (or vice versa) while default credential chain lookup is disabled.
Common situations: Partial secret injection (only one key mounted), copy-pasting a config template and forgetting the secret_key line, or intentionally disabling IMDS/env default credentials then supplying incomplete static creds.
Related errors
- s3.access.key and s3.secret.key is required with aws s3
- No auth method specified for Vault backend
- NATS connect mode `user_and_password` requires both `user` a
- NATS connect mode `credential` requires both `nkey` and `jwt
- `bigquery.local.path` and `bigquery.s3.path` set at least on
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/5e32f268d1d047b9.
Report an issue: GitHub.