risingwavelabs/risingwave · error
adlsgen2: cannot configure both shared-key auth (adlsgen2.ac
Error message
adlsgen2: cannot configure both shared-key auth (adlsgen2.account_key) and service-principal auth (adlsgen2.tenant_id / adlsgen2.client_id / adlsgen2.client_secret / adlsgen2.authority_host) simultaneously. Specify exactly one auth mode.
What it means
RisingWave's ADLS Gen2 connector for Iceberg tables supports two mutually exclusive auth modes: shared-key (account_key) and service-principal (OAuth with tenant_id/client_id/client_secret). This validation, run while assembling Iceberg catalog/file configs, rejects a with-props block that supplies fields for both modes at once, since the auth mode would be ambiguous.
Source
Thrown at src/connector/src/connector_common/iceberg/mod.rs:845
// `adlsgen2.tenant_id = ''` (or a value with trailing `\n` from a copy-paste)
// as `Some("...")` which would pass `is_some()` but break downstream auth.
fn nonempty(v: &Option<String>) -> Option<&str> {
v.as_deref().filter(|s| !s.trim().is_empty())
}
let sp_tenant = nonempty(&self.adlsgen2_tenant_id);
let sp_client = nonempty(&self.adlsgen2_client_id);
let sp_secret = nonempty(&self.adlsgen2_client_secret);
let sp_authority = nonempty(&self.adlsgen2_authority_host);
let sk_account_name = nonempty(&self.adlsgen2_account_name);
let sk_account_key = nonempty(&self.adlsgen2_account_key);
let any_sp_field = sp_tenant.is_some()
|| sp_client.is_some()
|| sp_secret.is_some()
|| sp_authority.is_some();
let all_sp_required = sp_tenant.is_some() && sp_client.is_some() && sp_secret.is_some();
if sk_account_key.is_some() && any_sp_field {
bail!(
"adlsgen2: cannot configure both shared-key auth \
(adlsgen2.account_key) and service-principal auth \
(adlsgen2.tenant_id / adlsgen2.client_id / adlsgen2.client_secret / \
adlsgen2.authority_host) simultaneously. Specify exactly one auth mode."
);
}
if any_sp_field && !all_sp_required {
bail!(
"adlsgen2: service-principal auth requires all three of \
adlsgen2.tenant_id, adlsgen2.client_id, and adlsgen2.client_secret \
to be set. (adlsgen2.authority_host is optional and defaults to the \
public Azure AAD endpoint.)"
);
}
// Defense in depth: reqsign POSTs the OAuth token request — carrying the
// client_secret to this host. Require a bare https origin: no userinfo,
// no query, no fragment, and no path beyond "/". The value itself is not
// echoed into error messages in case a user pasted a secret by mistake.View on GitHub (pinned to 6469eb736d)
Solutions
- Remove adlsgen2.account_key if you intend to use service-principal auth.
- Remove the adlsgen2.tenant_id/client_id/client_secret/authority_host fields if you intend to use shared-key auth.
- Ensure all four service-principal fields are present (authority_host optional) if keeping SP auth.
Example fix
-- before WITH ( 'adlsgen2.account_key' = 'xxx', 'adlsgen2.tenant_id' = 't', 'adlsgen2.client_id' = 'c', 'adlsgen2.client_secret' = 's' ) -- after WITH ( 'adlsgen2.tenant_id' = 't', 'adlsgen2.client_id' = 'c', 'adlsgen2.client_secret' = 's' )
Defensive patterns
Strategy: validation
Validate before calling
-- run before CREATE -- ensure exactly one auth mode: -- either adlsgen2.account_key alone, or tenant_id+client_id+client_secret together SELECT (account_key IS NOT NULL) XOR (tenant_id IS NOT NULL OR client_id IS NOT NULL OR client_secret IS NOT NULL OR authority_host IS NOT NULL) AS ok;
Prevention
- Keep one DDL template per auth mode and never merge them.
- Grep your with-props for both account_key and tenant_id before submitting.
- Remove stale fields when migrating auth modes.
When it happens
Trigger: Calling CREATE SINK/TABLE with an adlsgen2 endpoint where with-props include adlsgen2.account_key together with any of adlsgen2.tenant_id, adlsgen2.client_id, adlsgen2.client_secret, or adlsgen2.authority_host.
Common situations: Copy-pasting a config template that lists all auth options; switching auth modes and leaving the old account_key in place; a shared team config accumulating credentials from both modes.
Related errors
- adlsgen2: service-principal auth requires all three of adlsg
- adlsgen2.authority_host does not parse as a URL ({} chars)
- adlsgen2.authority_host must not contain a query or fragment
- adlsgen2.authority_host must not contain a path component
- `catalog.type` must be set
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/10c77c71d3548f86.
Report an issue: GitHub.