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

  1. 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.
  2. 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.
  3. 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

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


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