dotnet/yarp · critical · InvalidOperationException

The timeout was not applied for route '{route.Config.RouteId

Error message

The timeout was not applied for route '{route.Config.RouteId}', ensure `IApplicationBuilder.UseRequestTimeouts()` is called between `IApplicationBuilder.UseRouting()` and `IApplicationBuilder.UseEndpoints()`.

What it means

When a route has a `RequestTimeoutAttribute` in its endpoint metadata but no `IHttpRequestTimeoutFeature` is present on the HttpContext, it means the ASP.NET Core request timeouts middleware (`UseRequestTimeouts`) did not run or was placed incorrectly. YARP detects this mismatch and throws rather than silently allowing a request to proceed without its configured timeout — a safety-first design choice. The check is skipped when a debugger is attached to allow debugging.

Source

Thrown at src/ReverseProxy/Model/ProxyPipelineInitializerMiddleware.cs:108

            context.Features.Get<IHttpRequestTimeoutFeature>() is null &&
            // The feature is skipped if the request is already canceled. We'll handle canceled requests later for consistency.
            !context.RequestAborted.IsCancellationRequested &&
            // The policy may set the timeout to null / infinite.
            TimeoutPolicyRequestedATimeoutBeSet(requestTimeout))
        {
            // A timeout should have been set.
            // Out of an abundance of caution, refuse the request rather than allowing it to proceed without the configured timeout.
            ThrowIfDebuggerNotAttached(route);
        }

        void ThrowIfDebuggerNotAttached(RouteModel route)
        {
            // The feature is skipped if the debugger is attached.
            if (!Debugger.IsAttached)
            {
                Log.TimeoutNotApplied(_logger, route.Config.RouteId);

                throw new InvalidOperationException(
                    $"The timeout was not applied for route '{route.Config.RouteId}', " +
                    "ensure `IApplicationBuilder.UseRequestTimeouts()` is called between " +
                    "`IApplicationBuilder.UseRouting()` and `IApplicationBuilder.UseEndpoints()`.");
            }
        }
    }

    private bool TimeoutPolicyRequestedATimeoutBeSet(RequestTimeoutAttribute requestTimeout)
    {
        if (requestTimeout.Timeout is not TimeSpan timeout)
        {
            if (requestTimeout.PolicyName is not string policyName)
            {
                Debug.Fail("Either Timeout or PolicyName should have been set.");
                return false;
            }

            if (!_timeoutOptions.CurrentValue.Policies.TryGetValue(policyName, out var policy))

View on GitHub (pinned to bd11867bee)

Solutions

  1. Add `app.UseRequestTimeouts()` between `app.UseRouting()` and `app.UseEndpoints(...)` (or `app.MapReverseProxy()`) in Program.cs.
  2. Verify the ordering: `UseRouting` → `UseRequestTimeouts` → `UseEndpoints`/`MapReverseProxy`. If any are swapped, the timeout feature won't be set.
  3. If you don't want YARP to enforce request timeouts, remove the timeout configuration from the route/cluster config so no `RequestTimeoutAttribute` is attached.
  4. During local debugging, note that the throw is suppressed when a debugger is attached — so this may only reproduce in deployed environments.

Example fix

// before — UseRequestTimeouts missing
var app = builder.Build();
app.UseRouting();
app.MapReverseProxy(); // throws if route has timeout config
app.Run();
// after — correct middleware ordering
var app = builder.Build();
app.UseRouting();
app.UseRequestTimeouts();
app.MapReverseProxy();
app.Run();
Defensive patterns

Strategy: validation

Validate before calling

// At startup, verify the middleware pipeline ordering
// This is a code-structure assertion, not runtime:
/*
Correct order:
  app.UseRouting();
  app.UseRequestTimeouts();
  app.MapReverseProxy();
*/
// If timeouts are not configured on any route, UseRequestTimeouts is not needed.

Type guard

// No type guard — this is a middleware-ordering configuration issue.

Try / catch

// Not recommended — this is a fail-fast safety check by design.
// Fix the middleware ordering instead of catching the exception.

Prevention

When it happens

Trigger: A YARP route is configured with a timeout policy (`RequestTimeout` or a named timeout policy in the route config). The `RequestTimeoutAttribute` metadata is set on the endpoint. However, `IHttpRequestTimeoutFeature` is null because `app.UseRequestTimeouts()` was not called, or was called in the wrong position (not between `UseRouting()` and `UseEndpoints()`). The `EnsureRequestTimeoutPolicyIsAppliedCorrectly` method detects the missing feature and throws (unless a debugger is attached).

Common situations: A developer configures timeouts in the YARP config (`HttpRequest.ActivityTimeout` or timeout policies) but forgets to add `app.UseRequestTimeouts()` in Program.cs. The middleware is added but in the wrong order (after `UseEndpoints`, or before `UseRouting`). A framework upgrade changed where `UseRequestTimeouts` must be placed.

Understand the failure class

Related errors


AI-assisted analysis of dotnet/yarp@bd11867bee (2026-08-13). Data as JSON: /api/errors/538571b40dcd8962. Report an issue: GitHub.