BerriAI/litellm · error · HTTPException

Blocked by Cisco AI Defense Guardrail

Error message

Blocked by Cisco AI Defense Guardrail

What it means

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.

Source

Thrown at litellm/proxy/guardrails/guardrail_hooks/cisco_ai_defense/cisco_ai_defense.py:1076

        if action == _ACTION_REDACT:
            redacted: Final = self._apply_redaction(request_data, response_obj, context, verdict)
            if redacted:
                verbose_proxy_logger.info(
                    "Cisco AI Defense guardrail (%s): redaction applied (event_id=%s)",
                    context.surface,
                    verdict.event_id,
                )
                return inspect_response
            verbose_proxy_logger.warning(
                "Cisco AI Defense guardrail (%s): redact requested but no "
                "rewritable surface found — falling through to "
                "on_flagged_action=%s",
                context.surface,
                self.on_flagged_action,
            )

        if self.on_flagged_action == "block":
            raise HTTPException(
                status_code=400,
                detail=self._build_block_payload(context, verdict),
            )

        verbose_proxy_logger.info(
            "Cisco AI Defense guardrail (%s): violation in monitor mode — request allowed to proceed (event_id=%s)",
            context.surface,
            verdict.event_id,
        )
        return inspect_response

    @staticmethod
    def _stash_verdict_on_request(request_data: dict, context: _ScanContext, verdict: _CiscoVerdict) -> None:
        """Surface the Cisco verdict on the request metadata for observability."""
        metadata_store: Final = request_data.setdefault("metadata", {})
        if not isinstance(metadata_store, dict):
            return
        prefix: Final = f"cisco_ai_defense_{context.surface}_{context.direction}"

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Switch on_flagged_action to 'monitor' (log-only) while tuning policies so legitimate traffic isn't rejected.
  2. If masking is preferred, configure redaction (and ensure the violating surface is rewritable) so violations are redacted instead of blocked.
  3. 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.
  4. Client-side, handle HTTP 400 from the proxy as a policy block (surface the message to the user), not as a bug.

Example fix

# before — hard block on any violation
litellm_params:
  guardrail: cisco_ai_defense
  on_flagged_action: block

# after — observe first, block only confirmed-bad traffic later
litellm_params:
  guardrail: cisco_ai_defense
  on_flagged_action: monitor
Defensive patterns

Strategy: try-catch

Try / catch

try:
    resp = litellm.completion(..., guardrails=["cisco-ai-defense"])
except litellm.exception.HTTPException as e:
    if e.status_code == 400 and "Cisco AI Defense" in str(getattr(e, "detail", "")):
        event_id = extract_event_id(e.detail)  # correlate in Cisco console
        return policy_block_response(event_id)
    raise

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18). Data as JSON: /api/errors/154bd8acda92c009. Report an issue: GitHub.