BerriAI/litellm · error · HTTPException

Violated CrowdStrike AIDR guardrail policy

Error message

Violated CrowdStrike AIDR guardrail policy

What it means

HTTP 400 raised from the CrowdStrike AIDR guard hook when the guard API responds with result.blocked=true for the content checked on that event hook (pre-call prompt, post-call output, or MCP payload). This is the guardrail working as designed — a policy violation was detected — and the response detail includes guardrail_name for attribution, not an infrastructure failure.

Source

Thrown at litellm/proxy/guardrails/guardrail_hooks/crowdstrike_aidr/crowdstrike_aidr.py:315

            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json",
        }

        verbose_proxy_logger.debug(
            "CrowdStrike AIDR Guardrail (%s): Calling endpoint %s with payload: %s", hook_name, endpoint, payload
        )

        response: Final = await self.async_handler.post(url=endpoint, json=payload, headers=headers)
        assert response is not None
        response.raise_for_status()

        result = _GuardChatCompletionsResponse.model_validate(response.json()).result or _GuardChatCompletionsResult()

        if result.blocked:
            verbose_proxy_logger.warning(
                "CrowdStrike AIDR Guardrail (%s): Request blocked. Response: %s", hook_name, result
            )
            raise HTTPException(
                status_code=400,  # Bad Request, indicating violation
                detail={
                    "error": "Violated CrowdStrike AIDR guardrail policy",
                    "guardrail_name": self.guardrail_name,
                },
            )
        verbose_proxy_logger.debug(
            "CrowdStrike AIDR Guardrail (%s): Request passed. Response: %s", hook_name, result.detectors
        )

        return result

    def _build_guard_input_for_request(self, inputs: GenericGuardrailAPIInputs) -> _GuardInputWithIndices | None:
        guard_input: Final = _GuardInput(messages=[], tools=[])
        structured_messages: Final = inputs.get("structured_messages")
        texts: Final = inputs.get("texts", [])
        tools: Final = inputs.get("tools")

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Treat it as a policy verdict: change or remove the offending content — retrying the identical request will block again
  2. Review and narrow the detector policy for this workload in the CrowdStrike console
  3. Scope the guardrail: set default_on: false and attach it only to specific teams/API keys/paths via guardrail_info
  4. If unexpected, inspect the proxy warning log — it prints the full guard result (detectors) that produced blocked=true

Example fix

# before: retry loops on any error, blocks forever on a policy 400
resp = client.chat.completions.create(**params)

# after: branch on the guardrail 400 and stop retrying
try:
    resp = client.chat.completions.create(**params)
except Exception as e:
    body = getattr(getattr(e, 'response', None), 'json', lambda: {})() or {}
    err = body.get('error', {})
    if err == 'Violated CrowdStrike AIDR guardrail policy':
        return policy_denied(guardrail=body.get('guardrail_name'))
    raise
Defensive patterns

Strategy: try-catch

Try / catch

from fastapi import HTTPException

try:
    result = await proxied_chat_call(...)
except HTTPException as e:
    if e.status_code == 400 and isinstance(e.detail, dict) and e.detail.get('error') == 'Violated CrowdStrike AIDR guardrail policy':
        return policy_denied(guardrail=e.detail.get('guardrail_name'))  # no retry: deterministic verdict
    raise

Prevention

When it happens

Trigger: A request whose messages (pre-call hooks) or model output (post-call hooks) matches a CrowdStrike AIDR detector policy (PII such as SSNs/cards, prompt-injection patterns, restricted topics); response.raise_for_status() has already passed, so this is a semantic verdict, not an HTTP error from CrowdStrike.

Common situations: Test prompts containing realistic PII trip detectors; corporate policy configured too broadly in the CrowdStrike console; guardrail left default_on for all teams when intended for one; integration tests not expecting guardrail verdicts.

Related errors


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