{"record":{"id":"cc03db5958e66685","repo":"dotnet/yarp","slug":"the-ireverseproxyfeature-destinations-collection-w","errorCode":null,"errorMessage":"The IReverseProxyFeature Destinations collection was not set.","messagePattern":"The IReverseProxyFeature Destinations collection was not set\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/ReverseProxy/Delegation/HttpSysDelegatorMiddleware.cs","lineNumber":43,"sourceCode":"        IRandomFactory randomFactory)\n    {\n        ArgumentNullException.ThrowIfNull(next);\n        ArgumentNullException.ThrowIfNull(logger);\n        ArgumentNullException.ThrowIfNull(delegator);\n        ArgumentNullException.ThrowIfNull(randomFactory);\n        _next = next;\n        _logger = logger;\n        _delegator = delegator;\n        _randomFactory = randomFactory;\n    }\n\n    public Task Invoke(HttpContext context)\n    {\n        ArgumentNullException.ThrowIfNull(context);\n\n        var reverseProxyFeature = context.GetReverseProxyFeature();\n        var destinations = reverseProxyFeature.AvailableDestinations\n            ?? throw new InvalidOperationException($\"The {nameof(IReverseProxyFeature)} Destinations collection was not set.\");\n        var cluster = reverseProxyFeature.Cluster\n            ?? throw new InvalidOperationException($\"The {nameof(IReverseProxyFeature)} Cluster was not set.\");\n\n        if (destinations.Any())\n        {\n            // This logic mimics behavior in ForwarderMiddleware, except we save the chosen destination back\n            // to the proxy feature to ensure a delegation destination doesn't slip past this middleware.\n            var destination = destinations[0];\n            if (destinations.Count > 1)\n            {\n                var random = _randomFactory.CreateRandomInstance();\n                Log.MultipleDestinationsAvailable(_logger, reverseProxyFeature.Cluster.Config.ClusterId);\n                destination = destinations[random.Next(destinations.Count)];\n                reverseProxyFeature.AvailableDestinations = destination;\n            }\n\n            if (destination.ShouldUseHttpSysDelegation())\n            {","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/dotnet/yarp/blob/bd11867bee7df522e7fd3effb08a9c85fd616908/src/ReverseProxy/Delegation/HttpSysDelegatorMiddleware.cs#L25-L61","documentation":"Thrown by HttpSysDelegatorMiddleware.Invoke when IReverseProxyFeature.AvailableDestinations is null. The middleware expects an earlier pipeline stage (load balancing / proxy feature population) to have set the available destinations collection. A null value indicates the proxy feature was not initialized correctly for this request.","triggerScenarios":"The delegation middleware runs before the proxy has populated AvailableDestinations on the IReverseProxyFeature, or the feature itself was not attached to the context. Typically a middleware-ordering or pipeline-construction error.","commonSituations":"Placing UseHttpSysDelegation before UseLoadBalancing or before the proxy feature is set. Custom middleware clearing the feature. Misconfigured MapReverseProxy pipeline ordering.","solutions":["Ensure UseHttpSysDelegation is placed after load balancing and the proxy feature-populating middleware.","Do not mutate or null-out IReverseProxyFeature.AvailableDestinations in custom middleware.","Verify the route matched has a cluster with destinations configured."],"exampleFix":"// before — wrong order\napp.MapReverseProxy(p =>\n{\n    p.UseHttpSysDelegation(); // runs before destinations set\n    p.UseLoadBalancing();\n});\n// after\napp.MapReverseProxy(p =>\n{\n    p.UseLoadBalancing();\n    p.UseHttpSysDelegation();\n});","handlingStrategy":"validation","validationCode":"var feature = context.GetReverseProxyFeature();\nif (feature.AvailableDestinations is null)\n{\n    context.Response.StatusCode = 503;\n    return;\n}","typeGuard":"static bool HasDestinations(HttpContext ctx) =>\n    ctx.GetReverseProxyFeature().AvailableDestinations is not null;","tryCatchPattern":"try { await _next(context); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"Destinations collection was not set\"))\n{ context.Response.StatusCode = 503; }","preventionTips":["Order middleware: load balancing and feature population before delegation.","Never null out AvailableDestinations in custom middleware.","Test the pipeline end-to-end at startup."],"tags":["middleware","delegation","pipeline-ordering","reverse-proxy-feature"],"backgroundTag":null,"analyzedSha":"bd11867bee7df522e7fd3effb08a9c85fd616908","analyzedAt":"2026-08-13T21:29:49.359Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}