{"record":{"id":"1573eda9d2056183","repo":"dotnet/yarp","slug":"routing-endpoint-is-missing-typeof-routemodel-fu","errorCode":null,"errorMessage":"Routing Endpoint is missing {typeof(RouteModel).FullName} metadata.","messagePattern":"Routing Endpoint is missing (.+?) metadata\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"critical","filePath":"src/ReverseProxy/Model/ProxyPipelineInitializerMiddleware.cs","lineNumber":42,"sourceCode":"\n    public ProxyPipelineInitializerMiddleware(RequestDelegate next, ILogger<ProxyPipelineInitializerMiddleware> logger, IOptionsMonitor<RequestTimeoutOptions> timeoutOptions)\n    {\n        ArgumentNullException.ThrowIfNull(logger);\n        ArgumentNullException.ThrowIfNull(next);\n        ArgumentNullException.ThrowIfNull(timeoutOptions);\n\n        _logger = logger;\n        _next = next;\n        _timeoutOptions = timeoutOptions;\n    }\n\n    public Task Invoke(HttpContext context)\n    {\n        var endpoint = context.GetEndpoint()\n           ?? throw new InvalidOperationException($\"Routing Endpoint wasn't set for the current request.\");\n\n        var route = endpoint.Metadata.GetMetadata<RouteModel>()\n            ?? throw new InvalidOperationException($\"Routing Endpoint is missing {typeof(RouteModel).FullName} metadata.\");\n\n        var cluster = route.Cluster;\n        // TODO: Validate on load https://github.com/dotnet/yarp/issues/797\n        if (cluster is null)\n        {\n            Log.NoClusterFound(_logger, route.Config.RouteId);\n            context.Response.StatusCode = StatusCodes.Status503ServiceUnavailable;\n            return Task.CompletedTask;\n        }\n\n        EnsureRequestTimeoutPolicyIsAppliedCorrectly(context, endpoint, route);\n\n        var destinationsState = cluster.DestinationsState;\n        context.Features.Set<IReverseProxyFeature>(new ReverseProxyFeature\n        {\n            Route = route,\n            Cluster = cluster.Model,\n            AllDestinations = destinationsState.AllDestinations,","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/dotnet/yarp/blob/bd11867bee7df522e7fd3effb08a9c85fd616908/src/ReverseProxy/Model/ProxyPipelineInitializerMiddleware.cs#L24-L60","documentation":"After confirming an endpoint exists, the middleware expects it to carry `RouteModel` metadata — this is how YARP associates a matched endpoint with its route configuration. If the endpoint has no `RouteModel` in its metadata, the endpoint was not created by YARP's route-building process. This indicates a misconfiguration where a non-YARP endpoint (e.g., an MVC controller, a health check endpoint) is being processed by the YARP proxy pipeline.","triggerScenarios":"`context.GetEndpoint()` returns a non-null endpoint, but `endpoint.Metadata.GetMetadata<RouteModel>()` returns null. This means the matched endpoint was registered by something other than YARP's `MapReverseProxy` (e.g., an MVC route, a health check map, a static file endpoint) but the request somehow reached the proxy initializer middleware.","commonSituations":"A developer accidentally wraps non-proxy endpoints inside the `MapReverseProxy` pipeline. A health check or metrics endpoint is routed through the proxy middleware. The proxy middleware is registered as a global middleware rather than scoped to the reverse-proxy endpoint group.","solutions":["Ensure the `ProxyPipelineInitializerMiddleware` only runs for endpoints created by `MapReverseProxy` — keep non-proxy endpoints outside the proxy pipeline branch.","If using `app.MapReverseProxy(pipeline => { ... })`, make sure only proxy-related middleware is inside that branch; register other endpoints separately in `UseEndpoints`.","Verify that route patterns in the YARP config don't accidentally overlap with non-proxy endpoint patterns.","Check that no global `UseMiddleware<ProxyPipelineInitializerMiddleware>()` call exists outside the proxy endpoint mapping."],"exampleFix":"// before — health endpoint inside the proxy pipeline\napp.UseEndpoints(endpoints =>\n{\n    endpoints.MapReverseProxy(proxyPipeline =>\n    {\n        proxyPipeline.UseHealthChecks(\"/health\"); // wrong context\n        proxyPipeline.RunProxy();\n    });\n});\n// after — separate endpoints\napp.UseEndpoints(endpoints =>\n{\n    endpoints.MapHealthChecks(\"/health\"); // standalone\n    endpoints.MapReverseProxy();         // proxy only\n});","handlingStrategy":"validation","validationCode":"// Verify the endpoint has RouteModel metadata before relying on it\nvar endpoint = context.GetEndpoint();\nif (endpoint?.Metadata.GetMetadata<RouteModel>() is null)\n{\n    // This endpoint was not created by YARP\n    context.Response.StatusCode = 404;\n    return;\n}","typeGuard":"static bool IsYarpEndpoint(HttpContext context)\n    => context.GetEndpoint()?.Metadata.GetMetadata<RouteModel>() is not null;","tryCatchPattern":"// Not applicable — this is a pipeline-configuration error.\n// Fix by keeping non-proxy endpoints outside the MapReverseProxy pipeline.","preventionTips":["Keep health checks, metrics, and other non-proxy endpoints outside the MapReverseProxy branch.","Use the standard endpoint registration pattern: separate MapReverseProxy() from MapHealthChecks().","Verify that route patterns don't accidentally overlap between proxy and non-proxy endpoints."],"tags":["pipeline","routing","endpoint","metadata","misconfiguration"],"backgroundTag":null,"analyzedSha":"bd11867bee7df522e7fd3effb08a9c85fd616908","analyzedAt":"2026-08-13T21:29:49.359Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}