There are several built-in error responses. The body of each error response complies with RFC 7807: Problem Details.
In earlier versions, the error responses bodies complied with the Microsoft REST Guidelines error response format, which is itself the error response format used by the OData protocol (see OData JSON Format §21.1). There wasn't a broad standard at that time, which made any common error response format sensible.
Each problem detail also contains a code
extension to retain a level of backward compatibility for clients that may have relied on that value. If you need to retain the old functionality, refer to backward compatibility below.
API Version Unspecified
All versioned services require that an API version be specified. When a client makes a request without providing an API version, then the server will respond with a bad request. This behavior is typically not exhibited when the API is version-neutral or the AssumeDefaultVersionWhenUnspecified option is configured to true.
Title | Unspecified API version |
Type | https://docs.api-versioning.org/problems#unspecified |
Status | 400 |
Detail | An API version is required, but was not specified |
Code | ApiVersionUnspecified |
Unsupported API Version
When a client requested API version does not match any of the available controllers or their actions, then the server will respond with a problem. If the ReportApiVersions option is true, then the supported versions will be returned to the client in the api-supported-versions HTTP header.
Title | Unsupported API version |
Type | https://docs.api-versioning.org/problems#unsupported |
Status | 4001 2 |
Detail | The specified API version is not supported |
Code | UnsupportedApiVersion |
1: Defined by
ApiVersioningOptions.UnsupportedApiVersionStatusCode
2: The value is always404
when versioning by URL segment
Invalid API Version
When a client makes a request with an API version, but the value is malformed or cannot be parsed, then the server will respond with a bad request. This typically occurs where the value contains incomplete version components or the date-only form is invalid (ex: 2016-02-30).
Title | Invalid API version |
Type | https://docs.api-versioning.org/problems#invalid |
Status | 400 |
Detail | An API version was specified, but it is invalid |
Code | InvalidApiVersion |
Ambiguous API Version
When a client requests a specific API version, the specified API version must be unambiguous to the server. A client is allowed to specify an API version more than once, but if the values are not identical, then the server will respond with a bad request.
Title | Ambiguous API version |
Type | https://docs.api-versioning.org/problems#ambiguous |
Status | 400 |
Detail | An API version was specified multiple times with different values |
Code | AmbiguousApiVersion |
Examples
GET /resource?api-version=1.0 HTTP/1.1
host: localhost
api-version: 1.0
Figure 1: Multiple, unambiguous API versions requested
GET /resource?api-version=1.0 HTTP/1.1
host: localhost
api-version: 2.0
Figure 2: Ambiguous API versions requested between in query string and headers
GET /resource?api-version=1.0&api-version=2.0 HTTP/1.1
host: localhost
Figure 3: Ambiguous API versions requested in the query string
GET /resource HTTP/1.1
host: localhost
api-version: 1.0
api-version: 2.0
Figure 4: Ambiguous API versions requested in the headers
Customization
Error responses can be customized or extended in a variety of ways.
ASP.NET Web API
RFC 7807 was ratified after active development on ASP.NET Web API ceased. There are no out-of-the-box services provided. API Versioning provides a backport of the ProblemDetails
type as well as the IProblemDetailsFactory
. The default implementation can be replaced by implementing IProblemDetailsFactory
and exposing it as a resolvable service via HttpConfiguration.DependencyResolver
.
ASP.NET Core
Applies to .NET 7+
In ASP.NET Core, you must opt into using problem details via:
services.AddProblemDetails();
If problem details are not added, clients will receive an error response which only has the HTTP status code. You might choose this approach if you don't want a response body or your error responses do not comply with RFC 7807.
To modify the way a problem is written to clients, you can implement and register a your own IProblemDetailsWriter
implementation. Each registered implementation is injected into the IProblemDetailsService
. The first matching writer is used to write the response body. For more information see the ASP.NET Core Problem Details documentation.
Applies to .NET 6
The IProblemDetailsService
was not added to support ProblemDetails
in Minimal APIs and MVC Core until .NET 7. In API Versioning 6.x
, the IProblemDetailsFactory
interface was used to bridge this gap. Contrary to the opt-in behavior of AddProblemDetails()
, a default implementation of IProblemDetailsFactory
is automatically registered for Minimal APIs. If MVC Core is added, then a decorated adapter is automatically provided over ProblemDetailsFactory
. You have the choice of replacing the entire IProblemDetailsFactory
service or the MVC Core specific ProblemDetailsFactory
.
The IProblemDetailsFactory
interface was completely removed in .NET 7+ because it is no longer used in any way.
Backward Compatibility
While it is possible to customize error responses and retain the previous Error Object format, there is considerable work required to enable this behavior and may block adoption of new library versions. Additional extensions have been added to retain backward compatibility or continue to use Error Objects if you so desire.
ASP.NET Web API
Applies to 7.1.0+
ASP.NET Web API does not provide an out-of-the-box dependency injection container; however, the following extension method will wire up the necessary changes without having to add one of your own.
configuration.ConvertProblemDetailsToErrorObject();
ASP.NET Core
Using Error Object responses is as simple as registering the ErrorObjectWriter
to emit them. The critical part of each setup is the order in which the writer is registered. If the writer is not registered in the correct order, it will not be selected. Each configuration must occur before AddApiVersioning()
.
The default implementation of the ErrorObjectWriter
only writes Error Objects for API versioning related errors. The default ASP.NET Core behavior provided by AddProblemDetails()
is used for writing other types of errors. If you want to use Error Objects for other error responses, you can extend ErrorObjectWriter
and override which types of Problem Details it should match - perhaps all of them.
Applies to 8.1.0+
Using Minimal APIs
AddErrorObjects()
adds the default behavior; however, you can register a custom ErrorObjectWriter
via AddErrorObject<TWriter>()
. Both methods allow a custom Action<JsonOptions>
setup and will configure the default behavior if not otherwise specified.
builder.Services.AddProblemDetails().AddErrorObjects();
builder.Services.ApiVersioning();
Using Controllers
builder.Services.AddControllers();
builder.Services.AddErrorObjects().AddProblemDetails();
builder.Services.ApiVersioning().AddMvc();
Applies to 7.1.0+
Using Minimal APIs
builder.Services.AddProblemDetails();
builder.Services.TryAddEnumerable( ServiceDescriptor.Singleton<IProblemDetailsWriter, ErrorObjectWriter>() );
builder.Services.ApiVersioning();
Using Controllers
builder.Services.AddControllers();
builder.Services.TryAddEnumerable( ServiceDescriptor.Singleton<IProblemDetailsWriter, ErrorObjectWriter>() );
builder.Services.AddProblemDetails();
builder.Services.ApiVersioning().AddMvc();
Applies to .NET 6 and 6.5.0+
Since IProblemDetailsService
did not exist in .NET 6, you must instead replace IProblemDetailsFactory
with the ErrorObjectFactory
service. The configuration process and order are the same regardless of whether you are using Minimal APIs or controllers. The replaced service should occur before AddApiVersioning()
.
builder.Services.AddSingleton<IProblemDetailsFactory, ErrorObjectFactory>();
builder.Services.ApiVersioning();
- Home
- Quick Starts
- Version Format
- Version Discovery
- Version Policies
- How to Version Your Service
- API Versioning with OData
- Configuring Your Application
- Error Responses
- API Documentation
- Extensions and Customizations
- Known Limitations
- FAQ
- Examples