{"record":{"id":"5ca8816a7877f8c9","repo":"BerriAI/litellm","slug":"oauth-m2m-token-request-failed-e","errorCode":null,"errorMessage":"OAuth M2M token request failed: {e}","messagePattern":"OAuth M2M token request failed: (.+?)","errorType":"exception","errorClass":"DatabricksException","httpStatus":500,"severity":"error","filePath":"litellm/llms/databricks/common_utils.py","lineNumber":246,"sourceCode":"        workspace_url = api_base.rstrip(\"/\")\n        if \"/serving-endpoints\" in workspace_url:\n            workspace_url = workspace_url.replace(\"/serving-endpoints\", \"\")\n\n        token_url: Final = f\"{workspace_url}/oidc/v1/token\"\n\n        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.","sourceCodeStart":228,"sourceCodeEnd":264,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/llms/databricks/common_utils.py#L228-L264","documentation":"During Databricks OAuth machine-to-machine auth, LiteLLM posts to the workspace token endpoint (derived from api_base) with grant_type=client_credentials using DATABRICKS_CLIENT_ID/SECRET. The requests.post call itself raised RequestException — DNS failure, connection refused, TLS error, or the hardcoded 30s timeout — re-raised as DatabricksException(500) with the underlying exception text.","triggerScenarios":"M2M auth path taken (client_id + client_secret + api_base set) while the workspace host is unreachable: mistyped DATABRICKS_API_BASE producing a bad token URL, no egress to *.azuredatabricks.net/*.databricks.com, VPN-only workspace, corporate proxy unconfigured for requests, or slow handshakes exceeding 30s.","commonSituations":"K8s pod without egress rules allowing the Databricks host; DNS not resolving the workspace URL; HTTPS_PROXY not set in the container; cross-region latency causing the fixed timeout to fire.","solutions":["From the same host/network, curl https://<workspace-host>/oidc/v1/token — if that fails, fix DNS/proxy/egress before touching code","Correct DATABRICKS_API_BASE to the real workspace host (the token URL is derived by stripping /serving-endpoints)","Set HTTPS_PROXY/HTTP_PROXY if a corporate proxy is required for outbound traffic","If latency-driven, reduce network hops or run closer to the workspace region"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"import socket, os\nfrom urllib.parse import urlparse\n\ndef token_endpoint_reachable(timeout=5) -> bool:\n    host = urlparse(os.getenv('DATABRICKS_API_BASE', '')).hostname\n    if not host:\n        return False\n    try:\n        socket.create_connection((host, 443), timeout=timeout).close()\n        return True\n    except OSError:\n        return False","typeGuard":null,"tryCatchPattern":"from tenacity import retry, stop_after_attempt, wait_exponential\n\n@retry(stop=stop_after_attempt(3), wait=wait_exponential(min=1, max=10))\ndef call_databricks():\n    try:\n        return litellm.completion(model='databricks/my-ep', messages=msgs)\n    except Exception as e:\n        if 'OAuth M2M token request failed' in str(e) and getattr(e, 'status_code', 0) >= 500:\n            raise Retryable(e)  # network-level: DNS/proxy/timeout\n        raise","preventionTips":["Preflight connectivity to <workspace-host>:443 from every runtime environment at startup","Keep DATABRICKS_API_BASE pointing at the true workspace host so the derived token URL resolves","Configure proxy env vars in containers that require an egress proxy"],"tags":["databricks","oauth","m2m","network","timeout"],"backgroundTag":"oauth-token-request-failed","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}