Fixed: "Body was inferred but the method does not allow inferred body parameters" in a Minimal API
After I added one small GET endpoint, every request to my minimal API answered 500, health checks included. The log said Body was inferred but the method does not allow inferred body parameters. The endpoint took a record as a parameter, and ASP.NET Core assumes that comes from the JSON body, which GET doesn't get. [AsParameters] tells it to read the query string instead.
What I Was Doing
In a .NET 10 minimal API, I added a GET endpoint that takes a record, the same way a POST endpoint does:
public sealed record PlainProductRequest(string Sku, decimal UnitPrice, int ReorderLevel);
d.MapGet("/plain-record", (PlainProductRequest request) => Results.Ok(request));
It built with no errors, and the API started. Then I sent a request to a different endpoint, one that had always worked:
GET http://localhost:5190/api/v1/categories
What I Expected
200 OK. I hadn't touched that endpoint.
What I Got
A 500, and the same for every address I tried:
fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
An unhandled exception has occurred while executing the request.
System.InvalidOperationException: Body was inferred but the method does not allow inferred body parameters.
Below is the list of parameters that we found:
Parameter | Source
---------------------------------------------------------------------------------
request | Body (Inferred)
Did you mean to register the "Body (Inferred)" parameter(s) as a Service or apply the [FromServices] or [FromBody] attribute?

What I Checked
Which endpoint caused it. The table names one parameter, request, with the source Body (Inferred). It doesn't say which endpoint, but only one endpoint was new, and it was the only GET with a record parameter.
Why it reads from the body. ASP.NET Core's parameter binding page says: "Binding sources can be explicit or inferred based on HTTP method and parameter type." A class or record that isn't a service is assumed to be the JSON body. For GET, that assumption isn't allowed, because a GET isn't expected to have a body. That's the "method does not allow" in the message.
Why every endpoint fails. All the endpoints are built together when the first request needs them, so one that can't be built stops the whole lot. The API starts cleanly and fails on its first request, which makes it look like a much bigger problem.
Why It Happens
For a record parameter with no attribute, ASP.NET Core looks for a registered service, and then falls back to the request body. On GET, DELETE and similar methods that don't normally carry a body, that fallback is an error. The message offers the two ways out: "Did you mean to register the "Body (Inferred)" parameter(s) as a Service or apply the [FromServices] or [FromBody] attribute?" For a GET, neither of those is what you want, and there's a third way it doesn't mention.
The Fix
For values in the query string, which is what a GET should use, add [AsParameters], so each property of the record binds on its own:
d.MapGet("/asparameters-record", ([AsParameters] PlainProductRequest request) => Results.Ok(request));
If the data really belongs in a body, make it a POST:
d.MapPost("/plain-record", (PlainProductRequest request) => Results.Ok(request));
After the Fix
Every endpoint works again, and the new one reads the query string:
GET http://localhost:5190/demo/asparameters-record?sku=CBL-1&unitPrice=2.50&reorderLevel=3
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
"sku": "CBL-1",
"unitPrice": 2.50,
"reorderLevel": 3
}

Common Mistakes
| Mistake | What happens | Do this instead |
|---|---|---|
| Looking for the bug in the endpoint you called | Every endpoint fails because of one | Read the table, and check the newest endpoint |
Adding [FromBody] to a GET | It compiles, and clients must send a body on GET, which many can't | Use [AsParameters] |
Adding [FromQuery] to the record itself | It needs a TryParse for that type | Use [AsParameters] |
| Only testing the new endpoint on its own | You see the error, but not that it took down the rest | Run a known-good request too |
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
Body was inferred but the method does not allow inferred body parameters | A record or class parameter on GET, DELETE or similar | Use [AsParameters] |
A parameter is listed as UNKNOWN | A service that isn't registered | See that post |
Failure to infer one or more parameters naming two body parameters | Two records on a POST | Keep one body, and mark the others |
Every address answers 500 right after a code change | One endpoint can't be built | Read the log's parameter table |
FAQ
Why doesn't this fail when the app starts?
Endpoints are built the first time they're needed, not while starting. A request to anything triggers it.
Can a GET have a body?
HTTP doesn't forbid it, but many clients and proxies drop it, so ASP.NET Core won't assume one. Using the query string avoids the problem.
Conclusion
"Body was inferred but the method does not allow inferred body parameters" means a GET or DELETE endpoint has a record or class parameter with no attribute, and ASP.NET Core assumed it was a JSON body. It takes down every endpoint until it's fixed. Use [AsParameters] for query values, or make it a POST.
Additional Resources
- Parameter binding in Minimal API apps — binding sources and
[AsParameters].
