{"record":{"id":"154bd8acda92c009","repo":"BerriAI/litellm","slug":"blocked-by-cisco-ai-defense-guardrail","errorCode":null,"errorMessage":"Blocked by Cisco AI Defense Guardrail","messagePattern":"Blocked by Cisco AI Defense Guardrail","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"litellm/proxy/guardrails/guardrail_hooks/cisco_ai_defense/cisco_ai_defense.py","lineNumber":1076,"sourceCode":"        if action == _ACTION_REDACT:\n            redacted: Final = self._apply_redaction(request_data, response_obj, context, verdict)\n            if redacted:\n                verbose_proxy_logger.info(\n                    \"Cisco AI Defense guardrail (%s): redaction applied (event_id=%s)\",\n                    context.surface,\n                    verdict.event_id,\n                )\n                return inspect_response\n            verbose_proxy_logger.warning(\n                \"Cisco AI Defense guardrail (%s): redact requested but no \"\n                \"rewritable surface found — falling through to \"\n                \"on_flagged_action=%s\",\n                context.surface,\n                self.on_flagged_action,\n            )\n\n        if self.on_flagged_action == \"block\":\n            raise HTTPException(\n                status_code=400,\n                detail=self._build_block_payload(context, verdict),\n            )\n\n        verbose_proxy_logger.info(\n            \"Cisco AI Defense guardrail (%s): violation in monitor mode — request allowed to proceed (event_id=%s)\",\n            context.surface,\n            verdict.event_id,\n        )\n        return inspect_response\n\n    @staticmethod\n    def _stash_verdict_on_request(request_data: dict, context: _ScanContext, verdict: _CiscoVerdict) -> None:\n        \"\"\"Surface the Cisco verdict on the request metadata for observability.\"\"\"\n        metadata_store: Final = request_data.setdefault(\"metadata\", {})\n        if not isinstance(metadata_store, dict):\n            return\n        prefix: Final = f\"cisco_ai_defense_{context.surface}_{context.direction}\"","sourceCodeStart":1058,"sourceCodeEnd":1094,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/guardrails/guardrail_hooks/cisco_ai_defense/cisco_ai_defense.py#L1058-L1094","documentation":"HTTPException 400 raised by the Cisco AI Defense guardrail when a scan verdict is flagged, on_flagged_action is 'block', and redaction was either not requested or impossible (no rewritable surface found for redact). The detail body is built by _build_block_payload and carries the guardrail's structured block information (event_id, verdict data). This is an intentional policy block: the LLM call (or response delivery) is refused because Cisco classified the content as violating.","triggerScenarios":"Request or response content trips a Cisco AI Defense inspection policy (e.g., prompt injection, sensitive data) while the guardrail config sets on_flagged_action: block. Redaction paths fall through to block when 'redact' was requested but no rewritable surface exists for the violation (logged as a warning before the raise).","commonSituations":"Legitimate prompts containing security-research text flagged as prompt injection; model responses with secrets triggering DLP policies; teams initially running monitor mode then switching to block and being surprised by 400s; missing redact config forcing hard blocks where masking was intended.","solutions":["Switch on_flagged_action to 'monitor' (log-only) while tuning policies so legitimate traffic isn't rejected.","If masking is preferred, configure redaction (and ensure the violating surface is rewritable) so violations are redacted instead of blocked.","Retrieve the event_id from the 400 payload and look the verdict up in the Cisco AI Defense console to understand which policy fired, then narrow the policy.","Client-side, handle HTTP 400 from the proxy as a policy block (surface the message to the user), not as a bug."],"exampleFix":"# before — hard block on any violation\nlitellm_params:\n  guardrail: cisco_ai_defense\n  on_flagged_action: block\n\n# after — observe first, block only confirmed-bad traffic later\nlitellm_params:\n  guardrail: cisco_ai_defense\n  on_flagged_action: monitor","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    resp = litellm.completion(..., guardrails=[\"cisco-ai-defense\"])\nexcept litellm.exception.HTTPException as e:\n    if e.status_code == 400 and \"Cisco AI Defense\" in str(getattr(e, \"detail\", \"\")):\n        event_id = extract_event_id(e.detail)  # correlate in Cisco console\n        return policy_block_response(event_id)\n    raise","preventionTips":["Run on_flagged_action: monitor for a soak period before enabling block; tune policies using logged verdicts.","Keep event_id from block payloads and review them weekly to shrink false positives.","Client code should treat guardrail 400s as policy outcomes (message to user), never retry them.","Document for your users which content classes are blocked so they can avoid tripping policies."],"tags":["litellm","guardrails","cisco-ai-defense","content-moderation","blocked-request","policy"],"backgroundTag":"guardrail-content-blocked","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}