Skip to content

[Document Intelligence] queryFields against on-prem Layout container returns 202 then pins the operation at status=running forever (no terminal error) #47943

Description

@rbange
  • Package Name: azure-ai-documentintelligence
  • Package Version: 1.0.2 (azure-core 1.41.0)
  • Operating System: macOS (arm64); container image linux/amd64 (layout-4.0)
  • Python Version: 3.14.6

Describe the bug

Sending an analyze request with the queryFields add-on to an on-premises (connected)
Document Intelligence Layout container never completes. The initial POST …:analyze
returns 202 Accepted, but the operation then stays at "status": "running" indefinitely
and never transitions to succeeded or failed. Because poller.result() has no overall
deadline, the client hangs forever with no exception raised.

Two controls prove the request itself is valid:

  • The same request without queryFields succeeds against the same container in seconds.
  • The same request with queryFields succeeds against the cloud endpoint in seconds.

This implies the query-fields add-on isn't implemented in the container image — but instead of
failing the operation with a terminal error, the container leaves it pinned at running. The
container is idle (~2% CPU) throughout, so this is not a latency/throughput issue.

To Reproduce

Steps to reproduce the behavior:

  1. Run the connected Layout container:
    mcr.microsoft.com/azure-cognitive-services/form-recognizer/layout-4.0 (API 2024-11-30),
    with valid Eula/billing/apiKey (GET /status returns 200).

  2. Call begin_analyze_document with the query-fields add-on:

    import asyncio, io
    from azure.ai.documentintelligence.aio import DocumentIntelligenceClient
    from azure.ai.documentintelligence.models import DocumentAnalysisFeature
    from azure.core.credentials import AzureKeyCredential
    
    ENDPOINT = "http://localhost:5000"  # container does not validate the key
    
    async def main():
        async with DocumentIntelligenceClient(ENDPOINT, AzureKeyCredential("placeholder")) as client:
            with open("sample.pdf", "rb") as f:
                body = f.read()
            poller = await client.begin_analyze_document(
                "prebuilt-layout",
                body=io.BytesIO(body),
                features=[DocumentAnalysisFeature.QUERY_FIELDS],
                query_fields=["VendorName", "InvoiceTotal"],
            )
            result = await poller.result()   # never returns; no exception
            print(result)
    
    asyncio.run(main())
  3. Observe that the call never returns and never raises.

The same behavior at the HTTP level (isolates the SDK):

$ curl -s -D - -o /dev/null -X POST \
    "http://localhost:5000/documentintelligence/documentModels/prebuilt-layout:analyze?api-version=2024-11-30&features=queryFields&queryFields=VendorName,InvoiceTotal" \
    -H "Content-Type: application/octet-stream" --data-binary @sample.pdf
HTTP/1.1 202 Accepted
Operation-Location: http://localhost:5000/documentintelligence/documentModels/prebuilt-layout/analyzeResults/<guid>?api-version=2024-11-30

$ curl -s "http://localhost:5000/documentintelligence/documentModels/prebuilt-layout/analyzeResults/<guid>?api-version=2024-11-30"
{"status":"running", ...}
# polled repeatedly over minutes -> always "running", never "succeeded"/"failed"

Expected behavior

The operation transitions to "status": "failed" with a terminal error (e.g. InvalidArgument
or a "feature not supported by this container" message), so poller.result() raises
HttpResponseError promptly instead of hanging.

Screenshots

N/A — text output shown above (202 Accepted followed by an indefinite "status": "running").

Additional context

A/B/C evidence:

Request Backend Result
prebuilt-layout, no add-on on-prem container ✅ succeeds in seconds
prebuilt-layout + queryFields on-prem container status=running forever, no error
prebuilt-layout + queryFields cloud (Azure) ✅ succeeds in seconds, returns fields

Root cause appears to be the async LRO contract: the POST validates only the request envelope
(queryFields is a valid parameter in the 2024-11-30 contract the container shares with cloud),
so it returns 202 and queues an operation; the container then reaches the query-fields stage,
which isn't shipped in the image, and leaves the operation at running rather than transitioning
it to failed. Each poll is itself a valid 200 {"status":"running"}, so nothing raises.

Requests:

  1. Service/container: fail the operation with a terminal error when an unsupported add-on is
    requested, instead of leaving it at running.
  2. Docs: explicitly document which add-on capabilities (queryFields, keyValuePairs, …)
    are supported in the containers vs. cloud — this is currently undocumented.
  3. SDK (optional): consider a documented default overall deadline for the analyze poller, or
    clearer guidance, so a service-side operation stuck at running doesn't manifest as a silent,
    unbounded client hang.

Possibly related (not duplicates): #43085 (error handling), #42520 (LRO examples/timeouts),
#42152 (poller blocks loop), #43114 (polling_interval not respected), #36841 (error messaging
for unsupported inputs), #44449 (container + analyze, but 100% CPU — opposite symptom).

Metadata

Metadata

Assignees

Labels

ClientThis issue points to a problem in the data-plane of the library.Document Intelligencecustomer-reportedIssues that are reported by GitHub users external to the Azure organization.needs-team-attentionWorkflow: This issue needs attention from Azure service team or SDK teamquestionThe issue doesn't require a change to the product in order to be resolved. Most issues start as that

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions