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
- Remove the offending content (injection-like phrasing, embedded secrets/PII) from the prompt.
- Admins: tune the LLM Guard deployment's scanners (thresholds, enabled scanners) rather than disabling the hook wholesale.
- Check the LLM Guard service logs to see which scanner produced is_valid=false.
- 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
- Strip obvious prompt-injection phrasing and secrets from user input before sending.
- Tune LLM Guard scanner thresholds server-side to reduce false positives.
- Log rejected prompts (safely) to identify which scanner fires most.
- Treat the 400 as terminal — identical payloads will always be rejected.
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
- Keyword banned. Keyword={word}
- Violated content safety policy. Category={category}
- Violated content safety policy
- User blocked from making LLM API Calls. User={user}
- Violated content safety policy
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/560c2c2c2acda861.
Report an issue: GitHub.