BadHttpRequestException: Reading the request body timed out due to data arriving too slowly. See MinRequestBodyDataRate on ASP.NET core 2.2
Asked Answered
T

3

16

I'm using aspnetboilerplate solution developed with ASP.NET core 2.2 . The backend is deployed on azure and it uses the SQL server provided.

Sometimes, when the backend has a lot of requests to handle, it logs this exception:

ERROR 2020-11-20 12:28:21,968 [85 ] Mvc.ExceptionHandling.AbpExceptionFilter - Reading the request body timed out due to data arriving too slowly. See MinRequestBodyDataRate. Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException: Reading the request body timed out due to data arriving too slowly. See MinRequestBodyDataRate.

I tried to solve this problem adding this code to my Program.cs

 namespace WorkFlowManager.Web.Host.Startup
    {
        public class Program
        {
            public static void Main(string[] args)
            {
                var host = new WebHostBuilder()
                    .UseKestrel(options =>
                    {
                        options.Limits.MinResponseDataRate = null;
                    });
    
                BuildWebHost(args).Run();
            }
    
            public static IWebHost BuildWebHost(string[] args)
            {
                return WebHost.CreateDefaultBuilder(args)
                    .UseStartup<Startup>()
                    .Build();
            }
        }
    }

But the problem is not solved.

Tiller answered 20/11, 2020 at 16:38 Comment(1)
set to null was the solution for me. netcore 3.1Shakta
B
20

The exception you have shared indicates that application has a problem while "reading" the request.

Reading the request body timed out due to data arriving too slowly. See MinRequestBodyDataRate.

But you are trying to set MinResponseDataRate.

Please consider to update MinRequestBodyDataRate.

And instead of setting value to null, please examine the documentation and try to set meaningful values for request.

Default values are:

The default minimum rate is 240 bytes/second with a 5 second grace period.

And you can change like this:

.UseKestrel(options =>
    {
        options.Limits.MinRequestBodyDataRate =
            new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
    });
Bioclimatology answered 20/11, 2020 at 18:57 Comment(6)
i tried your solution but the problem still occurs..Tiller
Did you try to change bytesPerSecond and gracePeriod according to your needings? These values were just for example.Kreiner
oook, with new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(15)); the problem is solved. Thanks!Tiller
@Tiller could you add your using... line and or the required package? I have this error: The type or namespace name 'MinDataRate' could not be found (are you missing a using directive or an assembly reference?)Shakta
Why setting it to null is 'bad'?Byblow
What are you calling UseKestrel on? I can't find anything in net7 that has this. Or doesn't this work in net7?Scope
S
14

Alternatively to the accepted answer, this can also be due to the request headers not being consistent with the request body.

Two possible scenarios of bad requests are:

Incorrect Content-Length header

If the Content-Length's value is larger than the number of bytes passed in the request body.

Bad example:

POST /path HTTP/1.1
Content-Length: 15
Content-Type: text/plain

ABCDEFG

Where the request body is 7 characters long, but the header indicates it should be 15.

In this scenario the server will be waiting for 8 remaining bytes to be transmitted, which will never happen, forcing the error to occur.

Good example:

POST /path HTTP/1.1
Content-Length: 7
Content-Type: text/plain

ABCDEFG

Improperly terminated Transfer-Encoding: chunked message

If Transfer-Encoding: chunked is used instead of Content-Length and but the requestor fails to emit the end-of-body sequence.

Bad example:

POST /path HTTP/1.1
Transfer-Encoding: chunked
Content-Type: text/plain

4
ABCD
1
E
2
FG

Where the above example would need additionally 0 following two newlines (\r\n\r\n) to indicate the end of the request body.

Good example:

POST /path HTTP/1.1
Transfer-Encoding: chunked
Content-Type: text/plain

4
ABCD
1
E
2
FG
0

Shill answered 20/7, 2021 at 16:9 Comment(3)
So, is there anyway to handle that on the server side?Swihart
I doubt without writing your own (non-conforming) HTTP server, but even still it's probably not worthwhile to attempt as it'll be ambiguous to what the client was attempting to do. Did they erroneously send too much (or little) data, or did they just fail to calculate the length properly?Shill
They're not setting the Content-Length themselves, it's the framework that's setting it. But somehow, looks like it doesn't match. We're upgrading from .net framework 4.8 to .NET 6. The same request works on the framework version. No idea why :xSwihart
U
3

.NET 7

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(o => {
    o.Limits.MinRequestBodyDataRate = new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
});
Undeviating answered 11/5, 2023 at 9:53 Comment(2)
Answer needs supporting information Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Begird
@Begird is a spot on answer, what else is needed.Spleenful

© 2022 - 2024 — McMap. All rights reserved.