dotnet/yarp · error · InvalidOperationException
Current request can't be delegated. Either the request body
Error message
Current request can't be delegated. Either the request body has started to be read or the response has started to be sent.
What it means
Thrown by HttpSysDelegator.DelegateRequest when IHttpSysRequestDelegationFeature.CanDelegate is false. Http.sys delegation requires the request body not have been read and the response not have started; once bytes are sent or the body consumed, the connection can no longer be transparently handed off to a destination queue.
Source
Thrown at src/ReverseProxy/Delegation/HttpSysDelegator.cs:67
if (_queues.TryGetValue(key, out var queueWeakRef) && queueWeakRef.TryGetTarget(out var queue))
{
var detachedQueueState = queue.Detach();
Log.QueueReset(_logger, queueName, urlPrefix, detachedQueueState);
}
}
}
public void DelegateRequest(HttpContext context, DestinationState destination)
{
ArgumentNullException.ThrowIfNull(context);
ArgumentNullException.ThrowIfNull(destination);
var requestDelegationFeature = context.Features.Get<IHttpSysRequestDelegationFeature>()
?? throw new InvalidOperationException($"{typeof(IHttpSysRequestDelegationFeature).FullName} is missing.");
if (!requestDelegationFeature.CanDelegate)
{
throw new InvalidOperationException(
"Current request can't be delegated. Either the request body has started to be read or the response has started to be sent.");
}
if (_serverDelegationFeature is null || !_queuesPerDestination.TryGetValue(destination, out var queue))
{
Log.QueueNotFound(_logger, destination);
context.Response.StatusCode = StatusCodes.Status503ServiceUnavailable;
context.Features.Set<IForwarderErrorFeature>(new ForwarderErrorFeature(ForwarderError.NoAvailableDestinations, ex: null));
return;
}
Delegate(context, destination, _serverDelegationFeature, requestDelegationFeature, queue, _logger, shouldRetry: true);
static void Delegate(
HttpContext context,
DestinationState destination,
IServerDelegationFeature serverDelegationFeature,
IHttpSysRequestDelegationFeature requestDelegationFeature,View on GitHub (pinned to bd11867bee)
Solutions
- Ensure delegation is decided before any request body reads or response writes.
- Enable request body buffering (EnableBuffering) only if delegation is skipped, or move delegation before buffering.
- Reorder middleware so HttpSysDelegator runs ahead of any component that touches the body/response.
Example fix
// before — body read before delegation var body = await new StreamReader(context.Request.Body).ReadToEndAsync(); _delegator.DelegateRequest(context, destination); // CanDelegate == false // after — delegate first _delegator.DelegateRequest(context, destination);
Defensive patterns
Strategy: validation
Validate before calling
var feat = context.Features.Get<IHttpSysRequestDelegationFeature>();
if (feat is null || !feat.CanDelegate)
{
context.Response.StatusCode = 503;
return;
} Type guard
static bool CanDelegateNow(HttpContext ctx) =>
ctx.Features.Get<IHttpSysRequestDelegationFeature>()?.CanDelegate ?? false; Try / catch
try { _delegator.DelegateRequest(context, destination); }
catch (InvalidOperationException ex) when (ex.Message.Contains("can't be delegated"))
{ context.Response.StatusCode = 503; await context.Response.WriteAsync("Cannot delegate"); } Prevention
- Do not read the request body or write the response before delegation.
- Place delegation middleware early in the pipeline.
- Check CanDelegate before calling DelegateRequest.
When it happens
Trigger: Calling DelegateRequest after middleware has read from the request body stream, or after any response write/headers/HasStarted. The Http.sys feature refuses delegation in that state.
Common situations: A middleware earlier in the pipeline reads the request body (logging, buffering, auth). A response header or status is set before delegation. Response buffering middleware starts the response.
Related errors
- {typeof(IHttpSysRequestDelegationFeature).FullName} is not a
- {typeof(IHttpSysRequestDelegationFeature).FullName} is missi
- The IReverseProxyFeature Destinations collection was not set
- The IReverseProxyFeature Cluster was not set.
- The request cannot be forwarded, the response has already st
AI-assisted analysis of dotnet/yarp@bd11867bee (2026-08-13).
Data as JSON: /api/errors/50484b7b31b78593.
Report an issue: GitHub.