BerriAI/litellm · warning · HTTPException

Violated content safety policy

Error message

Violated content safety policy

What it means

Raised as HTTPException 400 by LLM Guard's moderation_check when the service's JSON response has is_valid: false, meaning the input prompt failed LLM Guard's sanitization/validation checks (prompt injection detection, input scanners). This is an intentional content-policy rejection. Note the surrounding try/except re-raises after logging via verbose_proxy_logger.exception.

Source

Thrown at enterprise/litellm_enterprise/enterprise_callbacks/llm_guard.py:81

                analyze_url = f"{self.llm_guard_api_base}analyze/prompt"
                verbose_proxy_logger.debug("Making request to: %s", analyze_url)
                async with aiohttp.ClientSession() as session:
                    async with session.post(
                        analyze_url, json={"prompt": text}
                    ) as response:
                        redacted_text = await response.json()
            verbose_proxy_logger.debug(
                f"LLM Guard: Received response - {redacted_text}"
            )
            if redacted_text is None:
                raise HTTPException(
                    status_code=500,
                    detail={
                        "error": f"Invalid content moderation response: {redacted_text}"
                    },
                )
            if redacted_text.get("is_valid", None) is False:
                raise HTTPException(
                    status_code=400,
                    detail={"error": "Violated content safety policy"},
                )
            sanitized_prompt = redacted_text.get("sanitized_prompt")
            return sanitized_prompt if isinstance(sanitized_prompt, str) else text
        except Exception as e:
            verbose_proxy_logger.exception(
                "litellm.enterprise.enterprise_hooks.llm_guard::moderation_check - Exception occurred - {}".format(
                    str(e)
                )
            )
            raise e

    def should_proceed(self, user_api_key_dict: UserAPIKeyAuth, data: dict) -> bool:
        if self.llm_guard_mode == "key-specific":
            # check if llm guard enabled for specific keys only
            self.print_verbose(
                f"user_api_key_dict.permissions: {user_api_key_dict.permissions}"

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Remove the offending content (injection-like phrasing, embedded secrets/PII) from the prompt.
  2. Admins: tune the LLM Guard deployment's scanners (thresholds, enabled scanners) rather than disabling the hook wholesale.
  3. Check the LLM Guard service logs to see which scanner produced is_valid=false.
  4. Client: treat the 400 as terminal for this payload — retrying unchanged will fail again.
Defensive patterns

Strategy: try-catch

Try / catch

try:
    sanitized = await moderation_check(text)
except HTTPException as e:
    if e.status_code == 400 and "content safety policy" in str(e.detail):
        raise PromptRejectedByLLMGuard(text_hint="possible injection/secrets") from e
    raise

Prevention

When it happens

Trigger: A request whose prompt text triggers LLM Guard's input scanners (e.g. PromptInjection scanner, secrets/anonymizer scanners), causing the /analyze/prompt response JSON to contain is_valid=false.

Common situations: Users pasting text that looks like prompt injection ('ignore previous instructions...'); legitimate content containing API keys/secrets being caught by the secrets scanner; scanner sensitivity set high in the LLM Guard deployment.

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/560c2c2c2acda861. Report an issue: GitHub.