{"record":{"id":"2b00b2da0d4df637","repo":"BerriAI/litellm","slug":"saml-response-exceeds-the-maximum-allowed-size","errorCode":null,"errorMessage":"SAML response exceeds the maximum allowed size.","messagePattern":"SAML response exceeds the maximum allowed size\\.","errorType":"http","errorClass":"HTTPException","httpStatus":413,"severity":"error","filePath":"litellm/proxy/management_endpoints/sso/saml_sso.py","lineNumber":291,"sourceCode":"        saml_settings: Final = OneLogin_Saml2_Settings(settings, sp_validation_only=True)\n        metadata: Final = cast(str, saml_settings.get_sp_metadata())  # cast-ok: untyped python3-saml\n        errors: Final = cast(list[str], saml_settings.validate_metadata(metadata))  # cast-ok: untyped python3-saml\n        if errors:\n            raise HTTPException(\n                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,\n                detail=f\"Invalid SP metadata: {', '.join(errors)}\",\n            )\n        return metadata\n\n    @staticmethod\n    async def read_acs_post_data(request: Request) -> dict[str, str]:\n        \"\"\"Read the ACS POST form under a hard size cap before any base64/XML decoding.\n\n        Bounds both Content-Length-declared and chunked requests so an unauthenticated\n        caller cannot force unbounded buffering while decoding the SAMLResponse.\"\"\"\n        declared: Final = request.headers.get(\"content-length\")\n        if declared is not None and declared.isdigit() and int(declared) > _SAML_MAX_POST_BYTES:\n            raise HTTPException(\n                status_code=status.HTTP_413_CONTENT_TOO_LARGE,\n                detail=\"SAML response exceeds the maximum allowed size.\",\n            )\n\n        body = bytearray()\n        async for chunk in request.stream():\n            body += chunk\n            if len(body) > _SAML_MAX_POST_BYTES:\n                raise HTTPException(\n                    status_code=status.HTTP_413_CONTENT_TOO_LARGE,\n                    detail=\"SAML response exceeds the maximum allowed size.\",\n                )\n\n        return dict(parse_qsl(body.decode(\"utf-8\", \"replace\")))\n\n    @staticmethod\n    async def handle_acs(request: Request, cache: DualCache, post_data: dict[str, str]) -> CustomOpenID:\n        auth: Final = await SAMLAuthHandler._build_auth(request, cache, post_data=post_data)","sourceCodeStart":273,"sourceCodeEnd":309,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/management_endpoints/sso/saml_sso.py#L273-L309","documentation":"read_acs_post_data streams the ACS POST body and enforces a size cap (_SAML_MAX_POST_BYTES); a SAML response larger than the cap is rejected with 413 before parsing, defending against oversized/malicious POSTs to the assertion consumer endpoint.","triggerScenarios":"Thrown at litellm/proxy/management_endpoints/sso/saml_sso.py:291 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Reduce the SAML response size (e.g., fewer group claims) or configure the IdP to send a smaller assertion."],"exampleFix":null,"handlingStrategy":"validation","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"}