dotnet / dotnet/aspnetcore

ProblemDetails should be the default error response for all HTTP error scenarios in ASP.NET Core

Open
#67,682 6 comments 2 reactions 0 assignees View on GitHub
area-minimal feature-problem-details
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 10h
Merged PRs (30d)
281

Description

### Is there an existing issue for this?

- [x] I have searched the existing issues

### Is your feature request related to a problem? Please describe the problem.

# Feature Request: `ProblemDetails` should be the default error response for all HTTP error scenarios in ASP.NET Core

## Description

Currently, ASP.NET Core has multiple inconsistent error response formats depending on where the error originates:

| Scenario | Response Format |
|---|---|
| `ControllerBase.Problem()` | `ProblemDetails` (RFC 9457) |
| `ExceptionMiddleware` custom | anonymous object / custom |
| Model validation errors | `ValidationProblemDetails` |
| `BadHttpRequestException` | plain text |
| Kestrel/Server errors | HTML or plain text |
| `StatusCodePages` middleware | varies |

As a result, developers must write boilerplate middleware, custom filters, and error handling code just to get a **consistent** RFC 9457 `ProblemDetails` response across all scenarios. This should be the built-in default.

## Request

- Make `ProblemDetails` the **default** response format for all 4xx/5xx errors in ASP.NET Core
- This includes server errors (Kestrel, IIS), model binding failures, authentication/authorization errors, and unhandled exceptions
- Provide a simple opt-out for those who want custom formats (like `IOptions` already allows)

## Why it matters

- Consistent API responses are a requirement for production-grade APIs
- Every other modern framework (Spring Boot, FastAPI, Gin) standardizes error responses
- It removes the need for every team to re-implement the same middleware

### Describe the solution you'd like

Make ProblemDetails the default serialization format for all built-in error responses:

1. Unhandled exceptions → ProblemDetails with status 500 (instead of HTML/plain text)
2. Bad HTTP requests (malformed body, invalid content type) → ProblemDetails with status 400
3. Authentication/Authorization failures → ProblemDetails with status 401/403
4. Model binding/validation errors → ProblemDetails with Errors dictionary (using ValidationProblemDetails)
5. Allow opt-out via Configure(o => o.CustomizeResponse = ...) for those who need custom formats.

The goal: app.UseProblemDetailsDefaults() should replace the 20+ lines of custom middleware every team writes today.

### Additional context

_No response_

Contributor guide

Open the contributing guide

Research direction

Start by mapping the existing Problem(), ExceptionMiddleware, model validation, BadHttpRequestException, authentication/authorization, Kestrel/IIS, and StatusCodePages paths mentioned in the issue. Review the ProblemDetailsOptions and the proposed UseProblemDetailsDefaults() entry point. Done means built-in 4xx/5xx scenarios consistently serialize as ProblemDetails or ValidationProblemDetails, with an opt-out for custom formats.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
api, backend
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
28/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.