Skip to content

Connecting to IPAddress.Any via HTTP/3 #108259

@amcasey

Description

@amcasey

Description

This is more of a question than a bug, so please let me know if this is by design.

We did find #95487 (which points to microsoft/msquic#2704) but, frankly, it was hard to follow and apply to our scenario.

TL;DR: When a (kestrel) server is listening on IPAddress.Any, HttpClient can connect to localhost with HTTP/1.1 and HTTP/2.0, but not with HTTP/3.0. You seem to have to either use 127.0.0.1 or switch to IPv6Any (which also works for 1.1 and 2.0).

This seems to happen in both dotnet 8.0 and 9.0.

Reproduction Steps

Server

using Microsoft.AspNetCore.Server.Kestrel.Core;
using System.Net;

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(options =>
{
    options.Listen(IPAddress.Any, 5001, listenOptions => // H3 to localhost doesn't work
    //options.Listen(IPAddress.IPv6Any, 5001, listenOptions => // H3 to localhost works
    {
        listenOptions.UseHttps();
        listenOptions.Protocols = HttpProtocols.Http1AndHttp2AndHttp3;
    });
});

var app = builder.Build();
 
app.MapGet("/", () => "Hello, world!");

app.Run();

Client

var handler = new SocketsHttpHandler(); 
handler.SslOptions.RemoteCertificateValidationCallback = (_, _, _, _) => true;

using var client = new HttpClient(handler)
{
    //BaseAddress = new Uri("https://127.0.0.1:5001"), // Works with ipv4 and ipv6
    //BaseAddress = new Uri("https://[::1]:5001"), // Works with ipv6
    BaseAddress = new Uri("https://localhost:5001"), // Works with ipv6
    DefaultRequestVersion = new Version(3, 0),
    DefaultVersionPolicy = HttpVersionPolicy.RequestVersionExact,
};

try
{
    Console.WriteLine("Requesting /");
    var response = await client.GetAsync("/");
    response.EnsureSuccessStatusCode();

    var data = await response.Content.ReadAsStringAsync();
    Console.WriteLine(data);
}
catch (HttpRequestException e)
{
    Console.WriteLine($"Request error: {e.Message}");
}

Expected behavior

Requesting /
Hello, world!

Actual behavior

Requesting /
Request error: Application layer protocol negotiation error was encountered. (localhost:5001)

Regression?

Not since 8.0, anyway. Possibly not even a bug.

Known Workarounds

In kestrel, it's more convenient to call ListenAnyIP anyway.

Configuration

Win11 x64. I appear to have dotnet 8.0.108 and 9.0.100-rc.1.24452.12, though the client may have been using whatever preview of 9.0 is in VS and the server would have been running aspnetcore main. I don't believe the specific dotnet versions matter, though the OS might.

Other information

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions