ThreeMammals/Ocelot · error · ArgumentOutOfRangeException
It is not a delegating handler
Error message
It is not a delegating handler
What it means
This is a validation guard inside the AddDelegatingHandler fluent method of IOcelotBuilder. The method registers a message-handler type as a transient DelegatingHandler service for Ocelot's HttpClient pipeline; before registering it checks that the supplied delegateType is actually assignable to DelegatingHandler. The input at fault is the caller-supplied delegateType argument: passing any type that does not derive from DelegatingHandler (e.g. a plain HttpClientHandler, an IHttpMessageHandler implementation that is not a DelegatingHandler, or an unrelated type) makes the generic constraint check fail and the error is thrown at DI-registration time, during Ocelot service configuration, before any request is handled.
Solutions
- Pass a Type that derives from System.Net.Http.DelegatingHandler, e.g. typeof(MyDelegatingHandler).
- If registering a delegate, use the AddDelegatingHandler(Func<DelegatingHandler>, bool) overload instead of the type-based overload.
- Verify with typeof(DelegatingHandler).IsAssignableFrom(delegateType) before calling AddDelegatingHandler.
- Ensure generics/assembly loading (e.g. reflection-based plugin loading) resolve to the DelegatingHandler subclass, not a base handler type such as HttpMessageHandler.
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at src/DependencyInjection/OcelotBuilder.cs:278 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of ThreeMammals/Ocelot@d1f22d9304 (2026-09-12).
Data as JSON: /api/errors/c6c4eda7f831087f.
Report an issue: GitHub.
Appendix: source
Thrown at src/DependencyInjection/OcelotBuilder.cs:278
return new DelegateInvokingLoadBalancerCreator<TLoadBalancer>(Create);
}
Services.AddSingleton<ILoadBalancerCreator>(implementationFactory);
return this;
}
/// <summary>
/// Adds a <see cref="DelegatingHandler"/> of the <paramref name="delegateType"/> type as a transient service, with the <paramref name="global"/> option to make the handler globally available.
/// </summary>
/// <param name="delegateType">The type of a <see cref="DelegatingHandler"/> to be registered.</param>
/// <param name="global">True if the handler should be globally available.</param>
/// <returns>A reference to the same <see cref="IOcelotBuilder"/> object.</returns>
/// <exception cref="ArgumentOutOfRangeException">Generates an exception if the <paramref name="delegateType"/> type does not inherit from the <see cref="DelegatingHandler"/>.</exception>
public IOcelotBuilder AddDelegatingHandler(Type delegateType, bool global = false)
{
if (!typeof(DelegatingHandler).IsAssignableFrom(delegateType))
{
throw new ArgumentOutOfRangeException(nameof(delegateType), delegateType.Name, "It is not a delegating handler");
}
if (global)
{
Services.AddTransient(delegateType);
Services.AddTransient(provider =>
{
var service = provider.GetService(delegateType) as DelegatingHandler;
return new GlobalDelegatingHandler(service);
});
}
else
{
Services.AddTransient(typeof(DelegatingHandler), delegateType);
}
return this;
}
View on GitHub (pinned to d1f22d9304)