title: How do you configure Kestrel to use a random dynamic port and determine the port at run-time with ASP.NET Core 3.1?
body: <p>With ASP.NET Core 3.0 I have been able to use this <code>IHostedService</code> method ...</p>
  
  <p><a href="https://stackoverflow.com/questions/49871318/determine-port-kestrel-binded-to">Determine port Kestrel binded to</a></p>
  
  <p>... to determine Kestrel's dynamic port at run-time.</p>
  
  <p><code>IServerAddressesFeature</code> is documented for ASP.NET 3.0 here:</p>
  
  <p><a href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.hosting.server.features.iserveraddressesfeature?view=aspnetcore-3.0" rel="nofollow noreferrer">https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.hosting.server.features.iserveraddressesfeature?view=aspnetcore-3.0</a></p>
  
  <p>But when changing the version to ASP.NET Core 3.1 then the page redirects back to ASP.NET 3.0 with the hint that the document is not available for ASP.NET Core 3.1. Is <code>IServerAddressesFeature</code> no longer working? Using <code>IServerAddressesFeature</code> with ASP.NET Core 3.1 still compiles, but the port in the returned <code>ServerAddresses</code> is always zero.</p>
  
  <p>Program:</p>
  
  <pre><code>public class Program
  {
      public static void Main(string[] args)
      {
          BuildWebHost().Run();
      }
  
      public static IWebHost BuildWebHost() =&gt;
  
          WebHost.CreateDefaultBuilder()
              .UseKestrel()
              .UseUrls("http://127.0.0.1:0") // port zero to use random dynamic port
              .UseStartup&lt;Startup&gt;()
              .Build();
  }
  </code></pre>
  
  <p>Later, when <code>Configure</code> is called ...</p>
  
  <pre><code>    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
      {
          HostedService.ServerAddresses = app.ServerFeatures.Get&lt;Microsoft.AspNetCore.Hosting.Server.Features.IServerAddressesFeature&gt;();
  </code></pre>
  
  <p>... the server addresses are assigned to the <code>HostedService.ServerAddresses</code> static variable as in the linked example. However, <code>ServerAddresses</code> contain only the loopback address with port zero: <code>"http://127.0.0.1:0"</code>.</p>
  
  <p>Am I overlooking something? Is there a different, proper way to resolve the problem in v3.1? How do I configure Kestrel to use a random dynamic port and determine which port it is at run-time (before any controller action takes place) with ASP.NET Core 3.1?</p>
  
  <p><strong>Update</strong></p>
  
  <p>Here is an ugly workaround that helps determine the port. It appears that the timing or sequence of dynamic port allocation has changed. Returning from the <code>HostedService.StartAsync</code> method and reading the server address a bit later seems to be enough. Surely there must be a better way?</p>
  
  <pre><code>        public Task StartAsync(CancellationToken cancellationToken)
          {
              System.Threading.Tasks.Task.Run(async () =&gt;
              {
                  int port = 0;
                  while (port == 0)
                  {
                      await System.Threading.Tasks.Task.Delay(250);
                      var address = ServerAddresses.Addresses.FirstOrDefault();
                      if (string.IsNullOrEmpty(address))
                          continue;
                      // address is always in form http://127.0.0.1:port
                      var pos = address.LastIndexOf(':');
                      if (pos &gt; 0)
                      {
                          var portString = address.Substring(pos + 1);
                          port = int.Parse(portString);
                      }
                  }
                  // have determined the dynamic port now
              });
              return System.Threading.Tasks.Task.CompletedTask;
          }
  </code></pre>