{"record":{"id":"43226df52a90d192","repo":"BerriAI/litellm","slug":"invalid-oauth-state-parameter-does-not-match-the","errorCode":null,"errorMessage":"Invalid OAuth state parameter — does not match the browser-bound state cookie.","messagePattern":"Invalid OAuth state parameter — does not match the browser-bound state cookie\\.","errorType":"http","errorClass":"ProxyException","httpStatus":400,"severity":"error","filePath":"litellm/proxy/management_endpoints/ui_sso.py","lineNumber":1594,"sourceCode":"\n        # Get authorization code from query params (only used in the PKCE path below;\n        # the non-PKCE path delegates to verify_and_process which handles OAuth error\n        # callbacks — user-denied, CSRF mismatch — internally).\n        authorization_code: Final = request.query_params.get(\"code\")\n\n        if code_verifier:\n            # State-to-session-cookie binding.  The non-PKCE branch below\n            # delegates to fastapi-sso's ``verify_and_process``, which\n            # performs its own session-cookie check.  The PKCE branch\n            # bypasses that helper, so we validate the URL ``state``\n            # against the ``litellm_oauth_state`` cookie set on the\n            # redirect response — without this an attacker can pre-mint\n            # a state + cached PKCE verifier and hijack a victim's auth\n            # code (Login-CSRF / token theft).\n            url_state: Final = request.query_params.get(\"state\")\n            cookie_state: Final = request.cookies.get(\"litellm_oauth_state\")\n            if not url_state or not cookie_state or not secrets.compare_digest(url_state, cookie_state):\n                raise ProxyException(\n                    message=(\"Invalid OAuth state parameter — does not match the browser-bound state cookie.\"),\n                    type=ProxyErrorTypes.auth_error,\n                    param=\"state\",\n                    code=status.HTTP_400_BAD_REQUEST,\n                )\n            if not authorization_code:\n                raise ProxyException(\n                    message=\"Missing authorization code in callback\",\n                    type=ProxyErrorTypes.auth_error,\n                    param=\"code\",\n                    code=status.HTTP_400_BAD_REQUEST,\n                )\n            if not generic_client_id:\n                raise ProxyException(\n                    message=\"GENERIC_CLIENT_ID must be set when PKCE is enabled\",\n                    type=ProxyErrorTypes.auth_error,\n                    param=\"GENERIC_CLIENT_ID\",\n                    code=status.HTTP_401_UNAUTHORIZED,","sourceCodeStart":1576,"sourceCodeEnd":1612,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/management_endpoints/ui_sso.py#L1576-L1612","documentation":"Error \"Invalid OAuth state parameter — does not match the browser-bound state cookie.\" thrown in BerriAI/litellm.","triggerScenarios":"Thrown at litellm/proxy/management_endpoints/ui_sso.py:1594 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Restart the SSO login flow in the same browser (cookies must be preserved); do not open the callback URL in a different browser."],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}