When sending an HTTP request, it is possible to transmit the data block by block (chunked). This makes it possible to avoid dealing with the total size of the data being exchanged and to send the content progressively. To do this, you must use the HTTP request header Transfer-Encoding: chunked
.
This sending mode is particularly useful in:
Thus, with chunked HTTP requests, applications become more responsive and encounter fewer errors when the transmitted content is smaller in volume.
To understand in detail how chunking works, you can refer to this page.
I developed an API (in Azure API Management) that receives an HTTP request and forwards its content to a Logic App. During the development testing phase, I used Postman to send the HTTP request to the API. Everything worked fine on my side, so I deployed my work.
However, I quickly noticed that my flow failed when consumed by a third-party system. Upon analyzing the executions, I saw that APIM did receive the request and that its content appeared in App Insights. However, in the Logic App, I only received the headers—not the request body:
I noticed an additional header in the execution generated by the third-party system compared to Postman: Transfer-Encoding: chunked
. I also saw that the Logic App only received the header without the request body. As a result, the Logic App failed in its second activity because it could not find the required information in the missing body.
To solve this HTTP chunked request issue, APIM must wait until it has received all the blocks from the sender before forwarding the data to the Logic App. To do this, add the following code in the inbound policy before calling the Logic App:
<set-body template="none"> @{ return context.Request.Body.As<string>(preserveContent: true); } </set-body>
<set-body template="none">
defines a new request body, replacing the chunked request block.context.Request.Body.As<string>(preserveContent: true)
accesses the incoming request body as a string.preserveContent: true
ensures the body stream is not consumed. APIM keeps the original body intact after fully reading each chunk.
This way, the system aggregates the entire incoming request body before sending it to the Logic App.
Now, the Logic App receives the request body and no longer sees the Transfer-Encoding: chunked
header.
We have solved the specific problem: an API exposed via Azure API Management was receiving a chunked request and forwarding it directly to the Logic App, causing issues. Now resolved, we can step back and examine how Azure more broadly handles chunked transfers. We will focus on three common Azure resources: APIM, Logic Apps, and Azure Functions.
As in our original issue, consider an API in APIM that, this time, does not call a Logic App but simply displays the request it receives.
Test #1: Sending a basic HTTP request without preserve-content
preserve-content
policy.
Result: APIM receives the full content without issue. The preserve-content
policy is not needed.
Test #2: Sending a chunked HTTP request without preserve-content
preserve-content
policy.
Result: APIM still receives the full content.
Conclusion: the preserve-content
policy is not required for APIM itself. In our original case, it was needed specifically for the Logic App component.
Consider a simple Logic App with an HTTP trigger:
Test #1: Sending a basic HTTP request
Result: The Logic App successfully receives the request body.
Test #2: Sending a chunked HTTP request
Conclusion: Logic Apps are not natively compatible with chunked HTTP requests.
We create a simple Azure Function with an HTTP trigger:
[Function(FUNCTION_NAME)] public async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequest req) { var streamReader = new StreamReader(req.Body); var body = await streamReader.ReadToEndAsync(); return new OkObjectResult(body); }
This code simply outputs the received request.
Test #1: Basic HTTP request
Test #2: Chunked HTTP request
Conclusion: Azure Functions are compatible with chunked HTTP requests.
This issue highlighted how chunked HTTP requests behave in these Azure components. Azure does not natively handle them well in our specific scenario: a request with the transfer-encoding: chunked
header sent to APIM, which then calls a Logic App. We found that the Logic App failed to receive the request body.
The fix was to adapt APIM policies to forward the body in a Logic App–compatible way by using preserve-content
to aggregate the entire body before sending it. As a result, the Logic App no longer receives the transfer-encoding: chunked
header and correctly gets the content. However, note that this removes the benefits of chunked transfer.
Broadening the analysis, we found that APIM itself works fine with chunked requests without additional policies. Calling a Logic App directly still reproduces the problem. Azure Functions work perfectly with chunked requests.
You can now design your flows with awareness of the potential impacts of third-party applications sending chunked HTTP requests.