BerriAI/litellm · error · ValueError
Azure Document Intelligence returned 202 but no Operation-Lo
Error message
Azure Document Intelligence returned 202 but no Operation-Location header found
What it means
Raised when the initial Azure DI submit returns HTTP 202 but the Operation-Location response header is absent, leaving LiteLLM no URL to poll for the async analysis result. Azure DI always includes this header on an accepted analyze request, so its absence indicates a protocol break — a proxy stripping headers, a wrong endpoint that returns 202 from something else, or an API-version mismatch.
Source
Thrown at litellm/llms/azure_ai/ocr/document_intelligence/transformation.py:584
self._check_timeout(start_time=start_time, timeout_secs=timeout_secs)
# Poll the operation status
response = await client.get(url=operation_url, headers=headers)
# Check operation status
status = self._check_operation_status(response=response)
if status == "succeeded":
return response
elif status == "running":
# Wait before polling again
retry_after = self._get_retry_after(response=response)
await asyncio.sleep(retry_after)
def _get_polling_target(self, raw_response: httpx.Response) -> tuple[str, dict[str, str]]:
operation_url: Final = raw_response.headers.get("Operation-Location")
if not operation_url:
raise ValueError("Azure Document Intelligence returned 202 but no Operation-Location header found")
# Reject cross-origin polling URLs — the auth headers
# below would otherwise leak to whatever URL the upstream
# (or an attacker-controlled upstream) returns. VERIA-51.
try:
assert_same_origin(operation_url, str(raw_response.request.url))
except SSRFError as ssrf_err:
raise ValueError(f"Azure Document Intelligence: rejected polling URL ({ssrf_err})")
poll_headers = {"Ocp-Apim-Subscription-Key": raw_response.request.headers.get("Ocp-Apim-Subscription-Key", "")}
return operation_url, poll_headers
def _transform_completed_response(self, model: str, raw_response: httpx.Response) -> OCRResponse:
"""
Transform a completed Azure Document Intelligence analyze operation
into the Mistral OCR response shape, preserving Azure-native
`analyzeResult` fields (`content`, `tables`, `keyValuePairs`) as
top-level response fields.View on GitHub (pinned to 6c2dcb801b)
Solutions
- Ensure api_base/AZURE_DOCUMENT_INTELLIGENCE_ENDPOINT points directly at your Document Intelligence resource and the model is a valid prebuilt/custom model ID.
- Check intermediaries (proxy/gateway) for header stripping and whitelist Operation-Location.
- Retry once — transient Azure anomalies do occur; if persistent, capture headers with curl to confirm what's returned.
Defensive patterns
Strategy: validation
Try / catch
try:
resp = litellm.aocr_document(model=m, document=doc)
except ValueError as e:
if "no Operation-Location header" in str(e):
raise InfrastructureError("DI endpoint/proxy dropped Operation-Location; check api_base and gateways") from e
raise Prevention
- Point api_base directly at the cognitive services resource.
- Ensure proxies/gateways forward the Operation-Location header.
- Mock servers must emit the header to be usable in tests.
When it happens
Trigger: An intermediary (corporate proxy, API gateway, custom base URL) returning its own 202 without forwarding Azure's Operation-Location; api_base pointing at a non-DI endpoint that happens to return 202; Azure API version changes altering response headers.
Common situations: Self-hosted gateways or mTLS terminators dropping unknown headers; misconfigured api_base; testing with mocks that don't emulate the header; rare Azure-side incidents.
Related errors
- Azure Document Intelligence: rejected polling URL ({ssrf_err
- Azure Document Intelligence operation polling timed out afte
- Azure Document Intelligence analysis failed: {error_msg}
- Unknown operation status: {status}
- Failed to parse Azure DI operation response: {e}
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/90a0f1e7484773b8.
Report an issue: GitHub.