BerriAI/litellm · error · HTTPException

guardrail_violation

guardrail_violation

Error message

guardrail_violation

What it means

GuardrailRaisedException is the generic guardrail rejection: an active guardrail (preset or custom) raised during the pre-call check of an MCP tool call. This handler converts it to HTTP 400 with error code guardrail_violation plus guardrail_name. It differs from blocked_pii_entity in that it covers any blocking guardrail decision, not only PII entity blocking.

Source

Thrown at litellm/proxy/_experimental/mcp_server/rest_endpoints.py:1067

                    "server_name": e.server_name,
                    "missing": e.missing,
                    "setup_url": e.setup_url,
                },
            )
        except BlockedPiiEntityError as e:
            verbose_logger.error("BlockedPiiEntityError in MCP tool call: %s", e)
            raise HTTPException(
                status_code=400,
                detail={
                    "error": "blocked_pii_entity",
                    "message": str(e),
                    "entity_type": getattr(e, "entity_type", None),
                    "guardrail_name": getattr(e, "guardrail_name", None),
                },
            )
        except GuardrailRaisedException as e:
            verbose_logger.error("GuardrailRaisedException in MCP tool call: %s", e)
            raise HTTPException(
                status_code=400,
                detail={
                    "error": "guardrail_violation",
                    "message": str(e),
                    "guardrail_name": getattr(e, "guardrail_name", None),
                },
            )
        except MCPUpstreamAuthError as e:
            # A client-forwarded pass-through upstream 401 from either the direct or the virtual call
            # branch. Relay it as a 401 + WWW-Authenticate so the MCP client can re-run upstream OAuth,
            # and log at info: an expected caller-must-reauth signal, not an operator-actionable error.
            verbose_logger.info("MCP tool call relaying upstream HTTP %s", e.status_code)
            raise _relay_upstream_auth_http_exception(e, request)
        except HTTPException as e:
            # Locally generated denials (tool/server permission, IP filtering, BYOK) stay at error level
            # so restriction probing keeps full monitoring visibility; the relayed upstream 401 above is
            # the only status demoted to info.
            verbose_logger.error("HTTPException in MCP tool call: %s", e)

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Read guardrail_name from the response and check that guardrail's logs to see which rule matched.
  2. Change the request content to satisfy the rule (remove banned terms/URLs/topics).
  3. Ask the admin to scope the guardrail so it does not block legitimate MCP tool traffic, or to adjust the rule thresholds.
Defensive patterns

Strategy: try-catch

Try / catch

except httpx.HTTPStatusError as e:
    d = e.response.json().get("detail", {})
    if e.response.status_code == 400 and isinstance(d, dict) and d.get("error") == "guardrail_violation":
        # guardrail_name identifies the rule set; do not blind-retry — content must change
        raise PolicyRejected(guardrail=d.get("guardrail_name"), reason=str(d.get("message"))) from e
    raise

Prevention

When it happens

Trigger: A guardrail in blocking mode (banned keywords/URLs/topics, prompt-injection or jailbreak detection) matches content in the tool call; guardrail hooks run inside the pre-call check and reject the request before it reaches the upstream MCP server.

Common situations: A security team enables strict guardrails on all traffic including MCP tools; agent prompts that quote untrusted web content trip keyword rules.

Related errors


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