{"record":{"id":"b6f8bf68adc52319","repo":"risingwavelabs/risingwave","slug":"adlsgen2-service-principal-auth-requires-all-thre","errorCode":null,"errorMessage":"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.)","messagePattern":"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\\.\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/connector/src/connector_common/iceberg/mod.rs","lineNumber":853,"sourceCode":"            let sp_authority = nonempty(&self.adlsgen2_authority_host);\n            let sk_account_name = nonempty(&self.adlsgen2_account_name);\n            let sk_account_key = nonempty(&self.adlsgen2_account_key);\n            let any_sp_field = sp_tenant.is_some()\n                || sp_client.is_some()\n                || sp_secret.is_some()\n                || sp_authority.is_some();\n            let all_sp_required = sp_tenant.is_some() && sp_client.is_some() && sp_secret.is_some();\n\n            if sk_account_key.is_some() && any_sp_field {\n                bail!(\n                    \"adlsgen2: cannot configure both shared-key auth \\\n                     (adlsgen2.account_key) and service-principal auth \\\n                     (adlsgen2.tenant_id / adlsgen2.client_id / adlsgen2.client_secret / \\\n                     adlsgen2.authority_host) simultaneously. Specify exactly one auth mode.\"\n                );\n            }\n            if any_sp_field && !all_sp_required {\n                bail!(\n                    \"adlsgen2: service-principal auth requires all three of \\\n                     adlsgen2.tenant_id, adlsgen2.client_id, and adlsgen2.client_secret \\\n                     to be set. (adlsgen2.authority_host is optional and defaults to the \\\n                     public Azure AAD endpoint.)\"\n                );\n            }\n            // Defense in depth: reqsign POSTs the OAuth token request — carrying the\n            // client_secret to this host. Require a bare https origin: no userinfo,\n            // no query, no fragment, and no path beyond \"/\". The value itself is not\n            // echoed into error messages in case a user pasted a secret by mistake.\n            if let Some(host) = sp_authority {\n                let parsed = Url::parse(host).map_err(|_| {\n                    anyhow!(\n                        \"adlsgen2.authority_host does not parse as a URL ({} chars)\",\n                        host.len()\n                    )\n                })?;\n                if parsed.scheme() != \"https\" {","sourceCodeStart":835,"sourceCodeEnd":871,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/connector_common/iceberg/mod.rs#L835-L871","documentation":"When any service-principal auth field is provided for an adlsgen2 Iceberg connection, all three of tenant_id, client_id and client_secret are mandatory; authority_host is optional. The connector bails out if only a partial subset is given, because OAuth client-credential flow cannot proceed without the full triple.","triggerScenarios":"Setting, e.g., only adlsgen2.client_id (or tenant_id + client_id without client_secret) while account_key is absent, so the connector detects SP mode but incomplete credentials.","commonSituations":"Redacting one secret when sharing DDL; forgetting client_secret; assuming tenant_id is optional; field named differently in the Azure portal than in with-props.","solutions":["Add the missing adlsgen2.tenant_id, adlsgen2.client_id, or adlsgen2.client_secret field(s).","If you meant shared-key auth instead, remove all SP fields and set adlsgen2.account_key (plus account name).","Optionally set adlsgen2.authority_host for sovereign clouds; it is not required."],"exampleFix":"-- before\nWITH (\n  'adlsgen2.tenant_id' = 't',\n  'adlsgen2.client_id' = 'c'\n)\n-- after\nWITH (\n  'adlsgen2.tenant_id' = 't',\n  'adlsgen2.client_id' = 'c',\n  'adlsgen2.client_secret' = 's'\n)","handlingStrategy":"validation","validationCode":"-- before submitting DDL, check the SP triple is complete:\n-- tenant_id, client_id and client_secret must all be present\nSELECT (tenant_id IS NOT NULL AND client_id IS NOT NULL AND client_secret IS NOT NULL) AS sp_complete;","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Store the SP triple as one unit (secret manager entry, env group) so fields never split.","List all four SP keys in your DDL checklist; authority_host optional.","Avoid manually redacting DDL — regenerate from a template."],"tags":["iceberg","adlsgen2","configuration","authentication"],"backgroundTag":"missing-required-config-field","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}