dotnet/yarp · error · InvalidOperationException
Chosen destination has no model set: '{destination.Destinati
Error message
Chosen destination has no model set: '{destination.DestinationId}' What it means
Thrown by ForwarderMiddleware.Invoke when the selected destination's Model property is null. DestinationState.Model holds the runtime DestinationConfig (address, health); a null model means the destination is in an incomplete/transitional state, e.g., it was removed during a config reload between selection and use. The forwarder cannot proceed without an address to proxy to.
Source
Thrown at src/ReverseProxy/Forwarder/ForwarderMiddleware.cs:76
activity?.AddError("Proxy forwarding failed", "No available destinations to forward to");
return;
}
var destination = destinations[0];
if (destinations.Count > 1)
{
var random = _randomFactory.CreateRandomInstance();
Log.MultipleDestinationsAvailable(_logger, cluster.ClusterId);
destination = destinations[random.Next(destinations.Count)];
}
reverseProxyFeature.ProxiedDestination = destination;
activity?.AddTag("proxy.destination_id", destination.DestinationId);
var destinationModel = destination.Model;
if (destinationModel is null)
{
throw new InvalidOperationException($"Chosen destination has no model set: '{destination.DestinationId}'");
}
try
{
cluster.ConcurrencyCounter.Increment();
destination.ConcurrencyCounter.Increment();
ForwarderTelemetry.Log.ForwarderInvoke(cluster.ClusterId, route.Config.RouteId, destination.DestinationId);
var clusterConfig = reverseProxyFeature.Cluster;
var result = await _forwarder.SendAsync(context, destinationModel.Config.Address, clusterConfig.HttpClient,
clusterConfig.Config.HttpRequest ?? ForwarderRequestConfig.Empty, route.Transformer);
activity?.SetStatus((result == ForwarderError.None) ? ActivityStatusCode.Ok : ActivityStatusCode.Error);
}
finally
{
destination.ConcurrencyCounter.Decrement();
cluster.ConcurrencyCounter.Decrement();View on GitHub (pinned to bd11867bee)
Solutions
- Reduce config reload churn or batch updates to minimize the race window.
- If custom-constructing DestinationState, always set Model to a valid DestinationModel.
- Treat as transient: the next request after reload should succeed; add retry at the caller if needed.
Example fix
// before — custom DestinationState without Model
var dest = new DestinationState("d1"); // Model stays null
// after
var dest = new DestinationState("d1",
new DestinationModel(new DestinationConfig { Address = "https://backend/api" })); Defensive patterns
Strategy: try-catch
Validate before calling
if (destination.Model is null)
{
context.Response.StatusCode = 503;
return;
} Type guard
static bool HasModel(DestinationState d) => d.Model is not null;
Try / catch
try { await _forwarder.SendAsync(...); }
catch (InvalidOperationException ex) when (ex.Message.Contains("no model set"))
{ context.Response.StatusCode = 503; // transient; reload race } Prevention
- Minimize config reload churn to reduce destination-model races.
- Always set Model when constructing DestinationState programmatically.
- Treat the error as transient and retry where appropriate.
When it happens
Trigger: A destination is selected from AvailableDestinations but its Model is null — typically because a config reload concurrently removed/ replaced the destination, leaving a stale DestinationState in the collection. Can also indicate a bug in destination lifecycle management.
Common situations: High-frequency config reloads racing with in-flight requests. Custom code injecting DestinationState objects without a Model. Destinations removed dynamically while requests are being routed.
Related errors
- Invalid destination prefix.
- {typeof(IHttpSysRequestDelegationFeature).FullName} is missi
- The IReverseProxyFeature Destinations collection was not set
- The request cannot be forwarded, the response has already st
- The http client must be of type HttpMessageInvoker, not Http
AI-assisted analysis of dotnet/yarp@bd11867bee (2026-08-13).
Data as JSON: /api/errors/b042bf6fa5e3ad3d.
Report an issue: GitHub.