{"record":{"id":"75d48f931a086d55","repo":"cube-js/cube","slug":"invalid-credentials-no-oauth-client-secret-provid","errorCode":null,"errorMessage":"Invalid credentials: No OAuth Client Secret provided","messagePattern":"Invalid credentials: No OAuth Client Secret provided","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/cubejs-databricks-jdbc-driver/src/DatabricksDriver.ts","lineNumber":230,"sourceCode":"    let showSparkProtocolWarn = false;\n    let url: string =\n      conf?.url ||\n      getEnv('databricksUrl', { dataSource, preAggregations }) ||\n      getEnv('jdbcUrl', { dataSource, preAggregations });\n    if (url.indexOf('jdbc:spark://') !== -1) {\n      showSparkProtocolWarn = true;\n      url = url.replace('jdbc:spark://', 'jdbc:databricks://');\n    }\n\n    const [uid, pwd, cleanedUrl] = extractAndRemoveUidPwdFromJdbcUrl(url);\n    const passwd = conf?.token ||\n          getEnv('databricksToken', { dataSource, preAggregations }) ||\n          pwd;\n    const oauthClientId = conf?.oauthClientId || getEnv('databricksOAuthClientId', { dataSource, preAggregations });\n    const oauthClientSecret = conf?.oauthClientSecret || getEnv('databricksOAuthClientSecret', { dataSource, preAggregations });\n\n    if (oauthClientId && !oauthClientSecret) {\n      throw new Error('Invalid credentials: No OAuth Client Secret provided');\n    } else if (!oauthClientId && oauthClientSecret) {\n      throw new Error('Invalid credentials: No OAuth Client ID provided');\n    } else if (!oauthClientId && !oauthClientSecret && !passwd) {\n      throw new Error('No credentials provided');\n    }\n\n    let authProps: Record<string, any> = {};\n\n    // OAuth has an advantage over UID+PWD\n    // For magic numbers below - see Databricks docs:\n    // https://docs.databricks.com/aws/en/integrations/jdbc-oss/configure#authenticate-the-driver\n    if (oauthClientId) {\n      authProps = {\n        OAuth2ClientID: oauthClientId,\n        OAuth2Secret: oauthClientSecret,\n        AuthMech: 11,\n        Auth_Flow: 1,\n      };","sourceCodeStart":212,"sourceCodeEnd":248,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/packages/cubejs-databricks-jdbc-driver/src/DatabricksDriver.ts#L212-L248","documentation":"The Databricks JDBC driver validates credential completeness at construction time: an OAuth client ID was supplied (option or env) but no OAuth client secret. OAuth requires both, so the driver fails fast with Invalid credentials instead of producing a broken JDBC connection later.","triggerScenarios":"new DatabricksDriver({...}) with oauthClientId set (or DATABRICKS_OAUTH_CLIENT_ID env) but oauthClientSecret missing (or DATABRICKS_OAUTH_CLIENT_SECRET unset), and no pwd/token fallback confusion — the pair is checked before password checks.","commonSituations":"Setting the client ID env var but forgetting the secret in the deployment environment; secrets not mounted in CI/K8s; partial copy-paste of OAuth config in cube.js datasourceOptions.","solutions":["Provide oauthClientSecret in the driver options or set DATABRICKS_OAUTH_CLIENT_SECRET","Verify the secret is present in the deployment environment (CI, K8s secret, .env)","If you intended token auth instead, remove the oauthClientId so password/token auth is used","Check per-dataSource/preAggregations env resolution — the secret may be defined only for a different dataSource"],"exampleFix":"// before\nconst driver = new DatabricksDriver({ url, oauthClientId: 'id' });\n// after\nconst driver = new DatabricksDriver({\n  url,\n  oauthClientId: 'id',\n  oauthClientSecret: process.env.DATABRICKS_OAUTH_CLIENT_SECRET,\n});","handlingStrategy":"validation","validationCode":"const clientId = conf?.oauthClientId || process.env.DATABRICKS_OAUTH_CLIENT_ID;\nconst clientSecret = conf?.oauthClientSecret || process.env.DATABRICKS_OAUTH_CLIENT_SECRET;\nif (clientId && !clientSecret) {\n  throw new Error('DATABRICKS_OAUTH_CLIENT_SECRET must be set when OAuth client id is used');\n}","typeGuard":"const hasValidOAuthPair = (c) =>\n  Boolean(c?.oauthClientId) === Boolean(c?.oauthClientSecret);","tryCatchPattern":"try {\n  driver = new DatabricksDriver(conf);\n} catch (e) {\n  if (/No OAuth Client Secret provided/.test(e.message)) {\n    throw new Error('Set DATABRICKS_OAUTH_CLIENT_SECRET in the deployment environment');\n  }\n  throw e;\n}","preventionTips":["Set DATABRICKS_OAUTH_CLIENT_ID and DATABRICKS_OAUTH_CLIENT_SECRET together in deployment config","Validate the full credential set at config-load time (fail at boot, not per query)","Verify secret mounts in K8s/CI include the client secret","Use one config object so ID and secret are always edited as a pair"],"tags":["databricks","oauth","configuration","credentials"],"backgroundTag":"oauth-client-secret-missing","analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}