启用QUIC/Http3时调用UseHttps()抛出ArgumentNullException异常
Kestrel启用QUIC/HTTP3时ArgumentNullException异常解决
异常信息
ERROR System.ArgumentNullException: Value cannot be null. (Parameter 'provider')
at System.ThrowHelper.Throw(String paramName)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
at Microsoft.AspNetCore.Hosting.ListenOptionsHttpsExtensions.UseHttps(ListenOptions listenOptions, HttpsConnectionAdapterOptions httpsOptions)
at NanoKestrel.<>c__DisplayClass16_0.<.ctor>b__2(ListenOptions listenOptions)
问题代码
public class NanoKestrel { public IServer Server { get; set; } private HostingApplication _application { get; set; } private X509Certificate2 _serverCertificate { get; set; } public NanoKestrel(IPEndPoint endPoint, X509Certificate2 certificate = null) { _serverCertificate = certificate; var services = new ServiceCollection(); services.AddLogging(b => { b.AddFilter("Microsoft.AspNetCore.Server.Kestrel", LogLevel.Warning); }); services.Configure<KestrelServerOptions>(options => { options.Listen(endPoint, listenOptions => { listenOptions.Protocols = HttpProtocols.Http1AndHttp2AndHttp3; if (_serverCertificate != null) listenOptions.UseHttps(new HttpsConnectionAdapterOptions() { ServerCertificate = _serverCertificate }); // <--exception thrown at this line in stacktrace }); }); services.AddSingleton<IServer, KestrelServer>(); services.AddSingleton<IConnectionListenerFactory, SocketTransportFactory>(); services.AddSingleton<IHostApplicationLifetime, ApplicationLifetime>(); services.AddTransient<IHttpContextFactory, DefaultHttpContextFactory>(); services.AddTransient<HostingApplication>(); var serviceProvider = services.BuildServiceProvider(); Server = serviceProvider.GetRequiredService<IServer>(); _application = serviceProvider.GetRequiredService<HostingApplication>(); } public async void StartAsync() { await Server.StartAsync(_application, default).ConfigureAwait(false); } }
问题背景
调用NanoKestrel构造函数时触发上述异常,尝试直接向listenOptions.UseHttps()传入证书仍报错,目标是在Kestrel上启用QUIC/HTTP3。
依赖信息
- 包引用:> Microsoft.Extensions.Features 7.0.2
- 框架引用:> Include="Microsoft.AspNetCore.App"
解决方案
异常根源是配置Kestrel选项时,listenOptions.UseHttps()需要依赖服务提供者,但此时服务容器尚未构建完成,无法获取所需服务。以下是修正方案:
修正后的代码
public class NanoKestrel { public IServer Server { get; set; } private HostingApplication _application { get; set; } private X509Certificate2 _serverCertificate { get; set; } public NanoKestrel(IPEndPoint endPoint, X509Certificate2 certificate = null) { _serverCertificate = certificate; var services = new ServiceCollection(); // 使用AddKestrel自动注册Kestrel所需全部依赖 services.AddKestrel(options => { options.Listen(endPoint, listenOptions => { listenOptions.Protocols = HttpProtocols.Http1AndHttp2AndHttp3; if (_serverCertificate != null) { listenOptions.UseHttps(_serverCertificate); } }); }) .AddLogging(b => { b.AddFilter("Microsoft.AspNetCore.Server.Kestrel", LogLevel.Warning); }); services.AddSingleton<IHostApplicationLifetime, ApplicationLifetime>(); services.AddTransient<IHttpContextFactory, DefaultHttpContextFactory>(); services.AddTransient<HostingApplication>(); var serviceProvider = services.BuildServiceProvider(); Server = serviceProvider.GetRequiredService<IServer>(); _application = serviceProvider.GetRequiredService<HostingApplication>(); } // 修正async void为async Task,避免异步生命周期问题 public async Task StartAsync() { await Server.StartAsync(_application, default).ConfigureAwait(false); } }
关键修正点
- 使用
AddKestrel()替代手动注册:该扩展方法会自动注册Kestrel运行所需的所有依赖项,包括HTTPS功能依赖的服务提供者,避免手动注册遗漏导致的空引用问题。 - 修正异步方法返回类型:将
async void改为async Task,async void仅适用于事件处理程序,普通异步方法返回Task才能正确管理异步生命周期。
内容的提问来源于stack exchange,提问作者Xiaoyu Zou
相关产品推荐
相关产品推荐

