Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QUIC: Port 50009 throws QUIC_STATUS_ADDRESS_IN_USE #71518

Open
JamesNK opened this issue Jul 1, 2022 · 10 comments
Open

QUIC: Port 50009 throws QUIC_STATUS_ADDRESS_IN_USE #71518

JamesNK opened this issue Jul 1, 2022 · 10 comments
Labels
area-System.Net.Quic tracking-external-issue The issue is caused by external problem (e.g. OS) - nothing we can do to fix it directly
Milestone

Comments

@JamesNK
Copy link
Member

JamesNK commented Jul 1, 2022

Description

In .NET 6 I have unit tests that start a Kestrel HTTP/3 endpoint on port 50019. It works fine.

I updated the unit test to .NET 7 and it now throws QUIC_STATUS_ADDRESS_IN_USE. Why is that? Is it a bug, or intentional behavior? If it's intentional then there should be documentation about what ports can be used.

Reproduction Steps

Small modification to the empty ASP.NET Core template to add a H3 port:

var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(c =>
{
    c.ListenLocalhost(50009, listner =>
    {
        listner.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http3;
        listner.UseHttps();
    });
});
var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.Run();

Expected behavior

Works

Actual behavior

System.IO.IOException
  HResult=0x80131620
  Message=Failed to bind to address https://localhost:50009.
  Source=Microsoft.AspNetCore.Server.Kestrel.Core
  StackTrace:
   at Microsoft.AspNetCore.Server.Kestrel.Core.LocalhostListenOptions.<BindAsync>d__2.MoveNext()
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.EndpointsStrategy.<BindAsync>d__2.MoveNext()
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.<BindAsync>d__0.MoveNext()
   at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerImpl.<BindAsync>d__33.MoveNext()
   at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerImpl.<StartAsync>d__30`1.MoveNext()
   at Microsoft.AspNetCore.Hosting.GenericWebHostService.<StartAsync>d__37.MoveNext()
   at Microsoft.Extensions.Hosting.Internal.Host.<StartAsync>d__12.MoveNext()
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.<RunAsync>d__4.MoveNext()
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.<RunAsync>d__4.MoveNext()
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.Run(IHost host)
   at Program.<Main>$(String[] args) in C:\Users\james\source\repos\WebApplication6\WebApplication6\Program.cs:line 14

  This exception was originally thrown at this call stack:
    Microsoft.Quic.MsQuic.ThrowIfFailure(int, string)
    System.Net.Quic.Implementations.MsQuic.MsQuicListener.Start(System.Net.Quic.QuicListenerOptions)
    System.Net.Quic.Implementations.MsQuic.MsQuicListener.MsQuicListener(System.Net.Quic.QuicListenerOptions)
    System.Net.Quic.QuicListener.ListenAsync(System.Net.Quic.QuicListenerOptions, System.Threading.CancellationToken)
    Microsoft.AspNetCore.Server.Kestrel.Transport.Quic.Internal.QuicConnectionListener.CreateListenerAsync()
    Microsoft.AspNetCore.Server.Kestrel.Transport.Quic.QuicTransportFactory.BindAsync(System.Net.EndPoint, Microsoft.AspNetCore.Http.Features.IFeatureCollection, System.Threading.CancellationToken)
    System.Threading.Tasks.ValueTask<TResult>.Result.get()
    Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure.TransportManager.BindAsync(System.Net.EndPoint, Microsoft.AspNetCore.Connections.MultiplexedConnectionDelegate, Microsoft.AspNetCore.Server.Kestrel.Core.ListenOptions, System.Threading.CancellationToken)
    Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerImpl.StartAsync.__OnBind|0(Microsoft.AspNetCore.Server.Kestrel.Core.ListenOptions, System.Threading.CancellationToken)
    Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.BindEndpointAsync(Microsoft.AspNetCore.Server.Kestrel.Core.ListenOptions, Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBindContext, System.Threading.CancellationToken)
    ...
    [Call Stack Truncated]

Inner Exception 1:
AggregateException: One or more errors occurred.

Inner Exception 2:
MsQuicException: ListenerStart failed: QUIC_STATUS_ADDRESS_IN_USE

Regression?

Yes

Known Workarounds

Use a different port

Configuration

No response

Other information

No response

@ghost ghost added the untriaged New issue has not been triaged by the area owner label Jul 1, 2022
@JamesNK JamesNK removed the untriaged New issue has not been triaged by the area owner label Jul 1, 2022
@ghost
Copy link

ghost commented Jul 1, 2022

Tagging subscribers to this area: @dotnet/ncl
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

In .NET 6 I have unit tests that start Kestrel on port 50019. I works fine.

I updated the unit test to .NET 7 and it now throws QUIC_STATUS_ADDRESS_IN_USE. Why is that? Is it a bug, or intentional behavior? If it's intentional then there should be documentation about what ports can be used.

Reproduction Steps

var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(c =>
{
    c.ListenLocalhost(50009, listner =>
    {
        listner.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http3;
        listner.UseHttps();
    });
});
var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.Run();

Expected behavior

Works

Actual behavior

System.IO.IOException
  HResult=0x80131620
  Message=Failed to bind to address https://localhost:50009.
  Source=Microsoft.AspNetCore.Server.Kestrel.Core
  StackTrace:
   at Microsoft.AspNetCore.Server.Kestrel.Core.LocalhostListenOptions.<BindAsync>d__2.MoveNext()
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.EndpointsStrategy.<BindAsync>d__2.MoveNext()
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.<BindAsync>d__0.MoveNext()
   at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerImpl.<BindAsync>d__33.MoveNext()
   at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerImpl.<StartAsync>d__30`1.MoveNext()
   at Microsoft.AspNetCore.Hosting.GenericWebHostService.<StartAsync>d__37.MoveNext()
   at Microsoft.Extensions.Hosting.Internal.Host.<StartAsync>d__12.MoveNext()
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.<RunAsync>d__4.MoveNext()
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.<RunAsync>d__4.MoveNext()
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.Run(IHost host)
   at Program.<Main>$(String[] args) in C:\Users\james\source\repos\WebApplication6\WebApplication6\Program.cs:line 14

  This exception was originally thrown at this call stack:
    Microsoft.Quic.MsQuic.ThrowIfFailure(int, string)
    System.Net.Quic.Implementations.MsQuic.MsQuicListener.Start(System.Net.Quic.QuicListenerOptions)
    System.Net.Quic.Implementations.MsQuic.MsQuicListener.MsQuicListener(System.Net.Quic.QuicListenerOptions)
    System.Net.Quic.QuicListener.ListenAsync(System.Net.Quic.QuicListenerOptions, System.Threading.CancellationToken)
    Microsoft.AspNetCore.Server.Kestrel.Transport.Quic.Internal.QuicConnectionListener.CreateListenerAsync()
    Microsoft.AspNetCore.Server.Kestrel.Transport.Quic.QuicTransportFactory.BindAsync(System.Net.EndPoint, Microsoft.AspNetCore.Http.Features.IFeatureCollection, System.Threading.CancellationToken)
    System.Threading.Tasks.ValueTask<TResult>.Result.get()
    Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure.TransportManager.BindAsync(System.Net.EndPoint, Microsoft.AspNetCore.Connections.MultiplexedConnectionDelegate, Microsoft.AspNetCore.Server.Kestrel.Core.ListenOptions, System.Threading.CancellationToken)
    Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerImpl.StartAsync.__OnBind|0(Microsoft.AspNetCore.Server.Kestrel.Core.ListenOptions, System.Threading.CancellationToken)
    Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.BindEndpointAsync(Microsoft.AspNetCore.Server.Kestrel.Core.ListenOptions, Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBindContext, System.Threading.CancellationToken)
    ...
    [Call Stack Truncated]

Inner Exception 1:
AggregateException: One or more errors occurred.

Inner Exception 2:
MsQuicException: ListenerStart failed: QUIC_STATUS_ADDRESS_IN_USE

Regression?

Yes

Known Workarounds

Use a different port

Configuration

No response

Other information

No response

Author: JamesNK
Assignees: -
Labels:

untriaged, area-System.Net.Quic

Milestone: -

@JamesNK JamesNK added the untriaged New issue has not been triaged by the area owner label Jul 1, 2022
@JamesNK
Copy link
Member Author

JamesNK commented Jul 1, 2022

The fix in my unit test project was to change the port to 55019.

Why 55019 works and 50019 now doesn't.... 🤷‍♂️

@wfurt
Copy link
Member

wfurt commented Jul 1, 2022

did you try to dump ports using netstat? AFAIK this error comes from Kernel. This could be sign of some old process sticking around.

@JamesNK
Copy link
Member Author

JamesNK commented Jul 1, 2022

50019 with .NET 6 = works
50019 with .NET 7 = error

I flipped back and forth a number of times to check that it was changing the .NET version that triggered it and nothing else. And I changed the port to a couple of other similar values, e.g. 50018, before discovering a bigger change like 55019 worked. Perhaps msquic doesn't allow listening on a range of ports by default?

I didn't use netstat.

The QUIC_STATUS_ADDRESS_IN_USE error is coming from MsQuicListener. It's in the stacktrace.

Repo is available to test. It's very simple.

@ManickaP ManickaP removed the untriaged New issue has not been triaged by the area owner label Jul 14, 2022
@ManickaP ManickaP added this to the 7.0.0 milestone Jul 14, 2022
@ManickaP
Copy link
Member

Triage: let's investigate for 7.0 and root cause this then we can decide what to do about it.

@rzikm rzikm self-assigned this Jul 14, 2022
@rzikm rzikm changed the title QUIC: Port 50019 throws QUIC_STATUS_ADDRESS_IN_USE QUIC: Port 50009 throws QUIC_STATUS_ADDRESS_IN_USE Jul 14, 2022
@rzikm
Copy link
Member

rzikm commented Jul 14, 2022

This does not look like .NET Runtime bug, the error comes from MsQuic.

I was able to reproduce this even outside MsQuic using the sample app from https://docs.microsoft.com/en-us/windows/win32/winsock/sio-acquire-port-reservation, the problematic range seems to be ports 50000-50059.

I filed issue with MsQuic to see if they can do something about it: microsoft/msquic#2891

@rzikm
Copy link
Member

rzikm commented Jul 14, 2022

There is something called Port Exclusion Ranges apparently that affects this:

> netsh int ip show excludedportrange protocol=udp

Protocol udp Port Exclusion Ranges

Start Port    End Port
----------    --------
     50000       50059     *
     55642       55741
     63552       63651

* - Administered port exclusions.

@rzikm
Copy link
Member

rzikm commented Jul 21, 2022

Tracking by (internal) OS issue: https://microsoft.visualstudio.com/OS/_workitems/edit/40464377

@rzikm rzikm added the tracking-external-issue The issue is caused by external problem (e.g. OS) - nothing we can do to fix it directly label Jul 21, 2022
@rzikm rzikm removed their assignment Jul 26, 2022
@karelz
Copy link
Member

karelz commented Aug 1, 2022

Triage: There is nothing we can do. It needs to be address in the OS. Moving to Future for tracking purposes.
If we see enough customers hitting it, we should document it properly.

@ManickaP
Copy link
Member

This is documented in out troubleshooting guide.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-System.Net.Quic tracking-external-issue The issue is caused by external problem (e.g. OS) - nothing we can do to fix it directly
Projects
None yet
Development

No branches or pull requests

5 participants