{"record":{"id":"6b8dc7c826c1163d","repo":"BerriAI/litellm","slug":"oauth-m2m-token-request-failed-response-text","errorCode":null,"errorMessage":"OAuth M2M token request failed: {response.text}","messagePattern":"OAuth M2M token request failed: (.+?)","errorType":"http","errorClass":"DatabricksException","httpStatus":null,"severity":"error","filePath":"litellm/llms/databricks/common_utils.py","lineNumber":252,"sourceCode":"        try:\n            response: Final = requests.post(\n                token_url,\n                data={\n                    \"grant_type\": \"client_credentials\",\n                    \"scope\": \"all-apis\",\n                },\n                auth=(client_id, client_secret),\n                headers={\"Content-Type\": \"application/x-www-form-urlencoded\"},\n                timeout=30,\n            )\n        except requests.RequestException as e:\n            raise DatabricksException(\n                status_code=500,\n                message=f\"OAuth M2M token request failed: {e}\",\n            )\n\n        if response.status_code != 200:\n            raise DatabricksException(\n                status_code=response.status_code,\n                message=f\"OAuth M2M token request failed: {response.text}\",\n            )\n\n        token_data: Final = response.json()\n        return token_data[\"access_token\"]\n\n    def _get_databricks_credentials(\n        self, api_key: str | None, api_base: str | None, headers: dict | None\n    ) -> tuple[str, dict]:\n        \"\"\"\n        Get Databricks credentials using the Databricks SDK.\n\n        Also registers LiteLLM as a partner for proper telemetry attribution\n        in Databricks system.access.audit table.\n\n        Args:\n            api_key: Optional API key (PAT)","sourceCodeStart":234,"sourceCodeEnd":270,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/llms/databricks/common_utils.py#L234-L270","documentation":"Raised when the Databricks OAuth M2M token endpoint responds but with a non-200 status. The exception carries the endpoint's status code and the raw response body (typically an OAuth error like invalid_client), telling you the request reached the server but authentication failed.","triggerScenarios":"Posting client_credentials grant with a bad client_id/client_secret (400 invalid_client), a service principal secret that expired or was rotated, missing 'all-apis' scope permissions, or a workspace where the service principal cannot authenticate.","commonSituations":"Rotated Databricks service-principal secrets not updated in env vars; OAuth secrets (not PATs) confused with DATABRICKS_API_KEY; secret typos or trailing whitespace/newlines when copied from a vault.","solutions":["Read response.text in the message — invalid_client means bad credentials, invalid_scope means permission issues","Regenerate the service principal secret in Databricks and update DATABRICKS_CLIENT_ID/DATABRICKS_CLIENT_SECRET","Strip whitespace from secret values loaded from files/vaults","Confirm the service principal has access to the workspace and serving endpoints"],"exampleFix":"# before\nclient_secret = open(\"secret.txt\").read()  # includes trailing \\n\n\n# after\nclient_secret = open(\"secret.txt\").read().strip()","handlingStrategy":"try-catch","validationCode":"client_id = os.getenv(\"DATABRICKS_CLIENT_ID\", \"\").strip()\nclient_secret = os.getenv(\"DATABRICKS_CLIENT_SECRET\", \"\").strip()\nassert client_id and client_secret, \"OAuth M2M credentials missing/blank\"","typeGuard":null,"tryCatchPattern":"try:\n    resp = litellm.completion(model=m, messages=msgs)\nexcept Exception as e:\n    if \"invalid_client\" in str(e):\n        raise ConfigError(\"Databricks service principal secret is wrong or expired\") from e\n    raise","preventionTips":["Strip() secrets loaded from files or vaults to remove stray newlines","Rotate service principal secrets on a schedule and update both env vars atomically","Alert on any non-200 token response — silent retry of bad credentials only burns lockout budget"],"tags":["databricks","oauth","authentication","credentials"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}