An Azure service that enables users to identify content that is potentially offensive, risky, or otherwise undesirable. Previously known as Azure Content Moderator.
Thank you for the detailed follow-up — you’ve raised very valid points, and I can see why this behavior feels inconsistent at first glance. Let me address your questions directly and suggest the best way to handle this moving forward.
- Why do filtered responses return HTTP 200 instead of 4xx?
This is expected behavior in Azure OpenAI (via Azure AI Foundry).
Content filtering is part of the model inference pipeline, not a request validation step. That means:
- HTTP 200 → The request was valid and processed successfully
If content is filtered → The model returns a safe/refusal response
HTTP 400 is only returned when the prompt itself is blocked before processing
In practice, you should rely on response fields such as:
finish_reason
The returned message content
…rather than HTTP status codes to detect filtering.
2. Why is content_filters sometimes null or missing?
This can happen and is consistent with current platform behavior.
Azure OpenAI applies:
Your configured content filter policy (e.g., “Annotate only”)
Plus additional built-in safety systems that are always enforced
When your configured policy triggers, you’ll typically see:
content_filter_results
prompt_filter_results
However, when filtering is triggered by internal safety mechanisms, the service may:
Return a refusal response
Not include detailed filter metadata (so content_filters may be null)
So while it looks like missing data, it doesn’t necessarily indicate a misconfiguration.
3. Why simple prompts may still get filtered
Even prompts like “What does <company> do?” can occasionally trigger filtering due to:
Entity ambiguity or pattern matching
Context from system prompts or prior messages
Probabilistic safety classifiers (which can produce false positives)
The exact trigger isn’t always exposed in the API response.
Recommended approach
To handle this reliably in your application:
- Detect filtering via response fields
- Check
finish_reason == "content_filter" - Look for refusal-style responses
- Check
- Treat filtering as a valid outcome
- Similar to partial or empty responses
- Log full request/response payloads
- Helps with troubleshooting and escalation
- Enable diagnostics
- Azure Monitor logs (
AzureOpenAIRequestLogs) may provide additional insight
- Azure Monitor logs (
If this HTTP 200 for filtered responses is by design
- HTTP 200 for filtered responses is by design
-
content_filtersis not guaranteed to always be populated - Some filtering decisions are not fully exposed today
Applications should rely on response inspection, not HTTP status codes
Microsoft Reference Links:
- https://learn.microsoft.com/azure/ai-services/openai/concepts/content-filter
- https://learn.microsoft.com/azure/ai-services/openai/how-to/content-filters
- https://learn.microsoft.com/azure/ai-services/openai/reference#chat-completions-response
Hope this helps. If you have any follow-up questions, please let me know. I would be happy to help.
Please do not forget to "Accept Answer" and "up-vote" wherever the information provided helps you, as this can be beneficial to other community members.