{"record":{"id":"89e067b25a35ed31","repo":"BerriAI/litellm","slug":"response-status-code-response-status-code","errorCode":null,"errorMessage":"Response status code: {response.status_code}","messagePattern":"Response status code: (.+?)","errorType":"http","errorClass":"HTTPException","httpStatus":null,"severity":"error","filePath":"litellm/proxy/guardrails/guardrail_hooks/zscaler_ai_guard/zscaler_ai_guard.py","lineNumber":358,"sourceCode":"                else:\n                    verbose_proxy_logger.error(\n                        \"Action field in response is %s, expecting 'ALLOW', 'BLOCK' or 'DETECT'\", guardrail_result\n                    )\n                    user_facing_error = self._create_user_facing_error(\n                        f\"Action field in response is {guardrail_result}, expecting 'ALLOW', 'BLOCK' or 'DETECT'\"\n                    )\n                    raise HTTPException(status_code=500, detail=user_facing_error)\n            else:\n                errorMsg: Final = json_response.get(\"errorMsg\", None)\n                verbose_proxy_logger.error(\"statusCode in response: %s, errorMsg: %s\", statusCode_in_response, errorMsg)\n                user_facing_error = self._create_user_facing_error(\n                    f\"statusCode in response: {statusCode_in_response}, errorMsg: {errorMsg}\"\n                )\n                raise HTTPException(status_code=500, detail=user_facing_error)\n        else:\n            verbose_proxy_logger.error(\"Zscaler AI Guard status_code - %s\", response.status_code)\n            user_facing_error = self._create_user_facing_error(f\"Response status code: {response.status_code}\")\n            raise HTTPException(status_code=response.status_code, detail=user_facing_error)\n\n    async def make_zscaler_ai_guard_api_call(\n        self, zscaler_ai_guard_url, api_key, policy_id, direction, content, **kwargs\n    ):\n        \"\"\"\n        Makes an API call to the Zscaler AI Guard service and handles retries, errors, and response parsing.\n        \"\"\"\n\n        extra_headers: Final = self._prepare_headers(api_key, **kwargs)\n\n        data: Final = {\n            \"direction\": direction,\n            \"content\": content,\n        }\n        # Only include policyId when explicitly configured (policy_id >= 1)\n        # When policy_id is None, 0, or -1 (default), use resolve-and-execute-policy which infers\n        # the policy from headers (e.g., user-api-key-alias)\n        if policy_id is not None and policy_id >= 1:","sourceCodeStart":340,"sourceCodeEnd":376,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/guardrails/guardrail_hooks/zscaler_ai_guard/zscaler_ai_guard.py#L340-L376","documentation":"Raised by the Zscaler AI Guard hook's _handle_response when the guardrail API answers with a status code that is neither 200 nor one of the specially handled errors (429, 5xx). Note that _send_request() calls response.raise_for_status() first, so 4xx/5xx actually surface through the generic handler at line 386; this branch therefore fires in practice for 3xx redirects or unexpected 2xx codes (e.g. 201, 202, 204). The proxy aborts the guarded LLM request and returns the upstream status code to the caller.","triggerScenarios":"A /chat/completions call on a proxy with a zscaler_ai_guard guardrail attached while the Zscaler endpoint replies with a redirect (301/302, httpx does not follow redirects by default) or an unusual 2xx such as 201/204. Typical when zscaler_ai_guard_url points at a base path or wrong API version instead of the exact AI Guard endpoint.","commonSituations":"zscaler_ai_guard_url (or ZSCALER_AI_GUARD_URL env var) missing or having an extra path segment so a different API shape responds; wrong Zscaler cloud/tenant host; an API gateway or corporate proxy in front of Zscaler rewriting status codes; Zscaler API behavior change after an upgrade.","solutions":["Set zscaler_ai_guard_url to the exact, full AI Guard API endpoint path for your Zscaler cloud (no trailing base URL)","Reproduce the raw call with curl -i from the proxy host using the same headers to see the actual status code and any Location header","Remove or fix any load balancer / corporate proxy in front of the Zscaler URL that may redirect or rewrite responses","Upgrade litellm to the latest release, since Zscaler response handling has changed across versions","If the service genuinely returns an unexpected 2xx for a correct request, open a case with Zscaler support"],"exampleFix":"# before (litellm_params in guardrail config)\nguardrail: zscaler_ai_guard\nzscaler_ai_guard_url: https://api.zscalercloud.net   # base host -> redirect / unexpected status\napi_key: os.environ/ZSCALER_API_KEY\n\n# after\napi_key: os.environ/ZSCALER_API_KEY","handlingStrategy":"try-catch","validationCode":"# Preflight from the proxy host: assert the guardrail endpoint answers 200 without following redirects\nimport httpx, os\n\nurl = os.environ['ZSCALER_AI_GUARD_URL']\nresp = httpx.post(\n    url,\n    headers={'x-api-key': os.environ['ZSCALER_API_KEY']},\n    json={'direction': 'REQUEST', 'content': 'ping'},\n    follow_redirects=False,\n    timeout=10,\n)\nassert resp.status_code == 200, f'unexpected status {resp.status_code} - fix URL before traffic flows'","typeGuard":null,"tryCatchPattern":"from openai import APIStatusError\n\ntry:\n    resp = client.chat.completions.create(model='gpt-4o', messages=[...])\nexcept APIStatusError as e:\n    # Guardrail re-raises the upstream Zscaler status; 3xx here almost always means URL misconfig\n    if 300 <= e.status_code < 400 or e.status_code in (201, 202, 204):\n        raise RuntimeError('zscaler_ai_guard_url points at a redirect/wrong endpoint') from e\n    raise","preventionTips":["Bake the exact full AI Guard endpoint URL into config and assert it ends with the documented path","Add a startup preflight that posts a benign 'ping' payload and requires HTTP 200","Pin the litellm version in deployments so Zscaler response handling does not change mid-release"],"tags":["guardrail","zscaler","http-status","upstream","redirect"],"backgroundTag":"upstream-api-error","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}