Skip to main content

How to Limit the Request Body Size in ASP.NET Core

· 4 min read
Jagdish Kumawat
Founder @ Dewiride

By default, ASP.NET Core reads a request body of up to about 28.6 MB. An API that takes small JSON documents has no use for that, and lowering it means a huge body gets turned away before your code spends any time on it.

What You Need​

The .NET 10 SDK, and a small project: dotnet new web --no-https -n WebDemo.

Step 1: Set the Limit​

Replace Program.cs. The limit is 1,024 bytes here, so that it's easy to reach:

Program.cs
var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(options =>
{
options.Limits.MaxRequestBodySize = 1024;
});

var app = builder.Build();

app.MapPost("/notes", (Note note) => note.Text.Length);

app.Run();

record Note(string Text);

MaxRequestBodySize is in bytes. A real API might use 1 MB, which is 1,048,576.

Step 2: Test Both Sides​

Terminal 1
dotnet run --no-launch-profile --urls http://localhost:5300

A small body gets through, and the answer is the length of the text. These send one of those, and then one of about 2 KB, over the limit:

Terminal
printf '{"Text":"%s"}' "$(head -c 2000 /dev/zero | tr '\0' x)" > big.json
curl -s -i -X POST http://localhost:5300/notes -H "Content-Type: application/json" -d '{"Text":"short"}'
curl -s -i -X POST http://localhost:5300/notes -H "Content-Type: application/json" -H "Expect:" -d @big.json
Output (the lines that matter)
HTTP/1.1 200 OK
5
HTTP/1.1 413 Payload Too Large

A short body answering 200 OK with the length 5, and a 2 KB body answering 413 Payload Too Large.

In the first tab, -H "Expect:" stops curl from pausing to ask the server first, which it can do for bigger bodies. With a real ASP.NET Core API using AddProblemDetails, the 413 also gets a body:

Response from an API with problem details
HTTP/1.1 413 Payload Too Large
Content-Type: application/problem+json
{"type":"https://tools.ietf.org/html/rfc9110#section-15.5.14","title":"Content Too Large","status":413,"traceId":"00-6acddb5bec50ec9782bfdf43f730e408-e8babaef6a868b74-00"}

Step 3: Keep the Number in Configuration​

The limit can't go straight into appsettings.json. Kestrel:Limits is silently ignored. To keep the number there anyway, read it from a section of your own:

appsettings.json
"RequestLimits": {
"MaxRequestBodyBytes": 1048576
}
Program.cs
using Microsoft.AspNetCore.Server.Kestrel.Core;

var maxRequestBodyBytes = builder.Configuration.GetValue<long>("RequestLimits:MaxRequestBodyBytes");

builder.Services.Configure<KestrelServerOptions>(options =>
options.Limits.MaxRequestBodySize = maxRequestBodyBytes);

One Endpoint That Needs More​

An upload endpoint can change it for its own requests, in a middleware that runs before the body is read. Microsoft's documentation shows this with IHttpMaxRequestBodySizeFeature, whose IsReadOnly tells you if it's too late. I didn't need it here, so I haven't tested it.

Common Mistakes​

MistakeWhat happensDo this instead
Testing with a small bodyIt looks fine, whether the limit works or notSend one over the limit
Putting it in appsettings.json under KestrelIt's ignoredSet it in code
Forgetting a reverse proxy has its own limitThe proxy answers firstSet that as well

Troubleshooting​

SymptomLikely causeFix
A big body gets a validation errorThe limit isn't active: the body was readThe fix
curl seems to stop at 100 ContinueIt's asking firstAdd -H "Expect:"
A 413 with no bodyNothing writes oneAdd AddProblemDetails and UseStatusCodePages

Conclusion​

Set Limits.MaxRequestBodySize in code, to what your API really takes, and prove it with a body that's too big.

Additional Resources​

Stay Updated

Subscribe to our newsletter for the latest tutorials, tech insights, and developer news.

By subscribing, you agree to our privacy policy. Unsubscribe at any time.