dotnet/yarp · error · InvalidOperationException
The {typeof(IReverseProxyFeature).FullName} is missing the {
Error message
The {typeof(IReverseProxyFeature).FullName} is missing the {typeof(RouteModel).FullName}. What it means
`GetRouteModel()` retrieves the `IReverseProxyFeature` from the `HttpContext` and then accesses its `Route` property. If the feature exists but `Route` is null, this means the proxy pipeline initialized the feature without associating a `RouteModel` — an internal inconsistency. This extension method is meant to be called during request processing within the proxy pipeline where routes are always populated.
Source
Thrown at src/ReverseProxy/Model/HttpContextFeaturesExtensions.cs:23
using Yarp.ReverseProxy.Model;
using Yarp.ReverseProxy.Forwarder;
namespace Microsoft.AspNetCore.Http;
/// <summary>
/// Extension methods for fetching proxy configuration from the current HttpContext.
/// </summary>
public static class HttpContextFeaturesExtensions
{
/// <summary>
/// Retrieves the <see cref="RouteModel"/> instance associated with the current request.
/// </summary>
public static RouteModel GetRouteModel(this HttpContext context)
{
var proxyFeature = context.GetReverseProxyFeature();
var route = proxyFeature.Route
?? throw new InvalidOperationException($"The {typeof(IReverseProxyFeature).FullName} is missing the {typeof(RouteModel).FullName}.");
return route;
}
/// <summary>
/// Retrieves the <see cref="IReverseProxyFeature"/> instance associated with the current request.
/// </summary>
public static IReverseProxyFeature GetReverseProxyFeature(this HttpContext context)
{
return context.Features.Get<IReverseProxyFeature>() ?? throw new InvalidOperationException($"{typeof(IReverseProxyFeature).FullName} is missing.");
}
/// <summary>
/// Retrieves the <see cref="IForwarderErrorFeature"/> instance associated with the current request, if any.
/// </summary>
public static IForwarderErrorFeature? GetForwarderErrorFeature(this HttpContext context)
{
return context.Features.Get<IForwarderErrorFeature>();View on GitHub (pinned to bd11867bee)
Solutions
- Ensure `GetRouteModel()` is only called within or after the YARP proxy pipeline (after `ProxyPipelineInitializerMiddleware` has run).
- If manually creating a `ReverseProxyFeature` (e.g., via `ReassignProxyRequest`), always copy the `Route` from the old feature.
- Use `context.GetReverseProxyFeature().Route` with a null check rather than `GetRouteModel()` if the route may legitimately be absent.
- Verify that the endpoint reaching your middleware was actually mapped through YARP's `MapReverseProxy()`.
Example fix
// before — manual feature creation without Route
var newFeature = new ReverseProxyFeature
{
Cluster = newCluster.Model,
AllDestinations = newCluster.DestinationsState.AllDestinations,
AvailableDestinations = newCluster.DestinationsState.AvailableDestinations,
Route = null // bug!
};
context.Features.Set(newFeature);
// after — always carry Route from the old feature
var oldFeature = context.GetReverseProxyFeature();
var newFeature = new ReverseProxyFeature
{
Cluster = newCluster.Model,
AllDestinations = newCluster.DestinationsState.AllDestinations,
AvailableDestinations = newCluster.DestinationsState.AvailableDestinations,
Route = oldFeature.Route // preserve route reference
};
context.Features.Set(newFeature); Defensive patterns
Strategy: validation
Validate before calling
// Safe access pattern for route model
var feature = context.Features.Get<IReverseProxyFeature>();
if (feature?.Route is null)
{
// Not in a proxied context, or feature not fully initialized
context.Response.StatusCode = 500;
return;
}
var route = feature.Route; Type guard
static RouteModel? TryGetRouteModel(HttpContext context)
{
return context.Features.Get<IReverseProxyFeature>()?.Route;
} Try / catch
// Not recommended to catch — use a null-safe access pattern instead. // If you must: only call GetRouteModel() from within the proxy pipeline.
Prevention
- Only call GetRouteModel() from code inside the YARP proxy pipeline.
- Use `context.Features.Get<IReverseProxyFeature>()?.Route` with a null check for defensive access.
- When constructing a new ReverseProxyFeature manually, always copy Route from the old feature.
When it happens
Trigger: `GetRouteModel()` is called in code that runs outside the YARP proxy pipeline (before `ProxyPipelineInitializerMiddleware` sets the feature), or the `IReverseProxyFeature` was manually created/overwritten with a `ReverseProxyFeature` instance whose `Route` property was left null. The check at line 22 finds `proxyFeature.Route == null` and throws.
Common situations: A developer calls `context.GetRouteModel()` in middleware that runs before the proxy pipeline has initialized the feature. Someone manually constructs a `ReverseProxyFeature` (e.g., in `ReassignProxyRequest`) and forgets to copy the `Route` property. Custom middleware replaces the feature with an incomplete instance.
Related errors
- {typeof(IReverseProxyFeature).FullName} is missing.
- Routing Endpoint wasn't set for the current request.
- The timeout was not applied for route '{route.Config.RouteId
- The IReverseProxyFeature Destinations collection was not set
- The IReverseProxyFeature Cluster was not set.
AI-assisted analysis of dotnet/yarp@bd11867bee (2026-08-13).
Data as JSON: /api/errors/898919f7c6978b01.
Report an issue: GitHub.