BerriAI/litellm · error · ContentPolicyViolationError
ContentPolicyViolationError: {exception_provider} - {message
Error message
ContentPolicyViolationError: {exception_provider} - {message} What it means
Normalized ContentPolicyViolationError: the provider rejected the content under its safety system. The mapping triggers on 'invalid_request_error'+'content_policy_violation', 'Invalid prompt ... violating our usage policy', or 'request was rejected as a result of the safety system' (case-insensitive). The message keeps the provider exception name and original provider text.
Source
Thrown at litellm/litellm_core_utils/exception_mapping_utils.py:325
message=f"{exception_provider} - {message}",
llm_provider=custom_llm_provider,
model=model,
response=getattr(original_exception, "response", None),
litellm_debug_info=extra_information,
)
elif "A timeout occurred" in error_str:
raise Timeout(
message=f"{exception_provider} - {message}",
model=model,
llm_provider=custom_llm_provider,
litellm_debug_info=extra_information,
)
elif (
("invalid_request_error" in error_str and "content_policy_violation" in error_str)
or ("Invalid prompt" in error_str and "violating our usage policy" in error_str)
or ("request was rejected as a result of the safety system" in error_str.lower())
):
raise ContentPolicyViolationError(
message=f"ContentPolicyViolationError: {exception_provider} - {message}",
llm_provider=custom_llm_provider,
model=model,
response=getattr(original_exception, "response", None),
litellm_debug_info=extra_information,
)
elif "invalid_encrypted_content" in error_str or "could not be verified" in error_str:
helpful_message: Final = (
f"{exception_provider} - {message}\n\n"
" This error occurs when load balancing Responses API across deployments with different API keys.\n"
" Encrypted content is tied to the organization that created it and cannot be decrypted by other organizations.\n\n"
" Solution: Enable 'encrypted_content_affinity' to route follow-up requests to the correct deployment:\n\n"
" router_settings:\n"
" enable_pre_call_checks: true\n"
" optional_pre_call_checks:\n"
" - encrypted_content_affinity\n\n"
" Learn more: https://docs.litellm.ai/docs/response_api#encrypted-content-affinity-multi-region-load-balancing"
)View on GitHub (pinned to 6c2dcb801b)
Solutions
- Inspect the provider's message (kept in the exception) to see which part triggered it; sanitize or rephrase the offending prompt segments and avoid embedding untrusted user text verbatim.
- Add pre-call moderation/filtering of user input, and post-failure handling that surfaces a friendly message instead of retrying — retrying the identical request always fails.
- If the use case is policy-compliant, consider a provider/deployment with an appropriate content filter configuration (e.g. Azure content filters) and route those requests there.
Example fix
# before
litellm.completion(model="gpt-4o", messages=[{"role":"user","content":raw_user_text}])
# -> ContentPolicyViolationError
# after
from litellm import ContentPolicyViolationError
try:
resp = litellm.completion(model="gpt-4o", messages=safe_messages(raw_user_text))
except ContentPolicyViolationError:
return graceful_refusal() # do NOT retry identical input Defensive patterns
Strategy: try-catch
Validate before calling
null
Type guard
from litellm import ContentPolicyViolationError
def is_content_policy_error(exc: BaseException) -> bool:
return isinstance(exc, ContentPolicyViolationError) Try / catch
from litellm import ContentPolicyViolationError
try:
resp = litellm.completion(model=m, messages=msgs)
except ContentPolicyViolationError as e:
log_rejected_prompt(msgs, str(e)) # audit which segment triggered it
return polite_refusal() # do NOT retry identical input Prevention
- Sanitize/rephrase untrusted user text before embedding it in prompts.
- Never auto-retry this error; handle it as a permanent rejection.
- Route policy-sensitive but legitimate workloads to appropriately configured filter levels.
When it happens
Trigger: Prompts or completions touching content the provider blocks: flagged keywords, certain medical/violence/adult topics, embedded URLs/domains with bad reputation, or images tripping moderation. The provider returns the matching error string and litellm re-raises this normalized type.
Common situations: Legitimate-but-sensitive domains (security research, healthcare, fiction) tripping filters; user-generated content forwarded unfiltered into prompts; prompt-injection or poisoned data causing systematic refusals; stricter new provider policy rolling out and previously-working prompts suddenly failing.
Related errors
- ContextWindowExceededError: {exception_provider} - {message}
- {exception_provider} - {message}
- Error in response: {raw_response.error}
- {service_name} returned non-dict JSON ({type(result).__name_
- {self.custom_llm_provider} raised a streaming error - finish
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/bb7165589c297bb5.
Report an issue: GitHub.