dotnet / dotnet/runtime

SocketsHttpHandler TLS handshake fails with 'Broken pipe' over IPv6 on macOS 26 Tahoe (.NET 10)

Open
#127,283 3 comments 0 reactions 0 assignees View on GitHub
area-System.Net.Http needs-author-action
Dominant language
C#
Stars
18.3k
Forks
5.6k
PR merge metrics
PR metrics pending

Description

## Description

`dotnet restore` (and any `HttpClient` request via `SocketsHttpHandler`) fails to connect to `api.nuget.org` on macOS 26 Tahoe with .NET 10. The TLS handshake breaks with "Broken pipe" when the connection goes over IPv6.

## Error

```
error NU1301: Unable to load the service index for source https://api.nuget.org/v3/index.json.
The SSL connection could not be established, see inner exception.
Unable to write data to the transport connection: Broken pipe.
Broken pipe
```

## Environment

```
SDK: 10.0.105
Runtime: 10.0.5
OS: macOS 26.4.1 (Tahoe) — Apple Silicon (osx-arm64)
Installed via: Homebrew
```

Full `dotnet --info`:
```
SDK DE .NET:
Version: 10.0.105
Commit: a612c2a105
Workload version: 10.0.100-manifests.0793c108
MSBuild version: 18.0.11+a612c2a10

Host:
Version: 10.0.5
Architecture: arm64
Commit: a612c2a105

.NET runtimes installed:
Microsoft.AspNetCore.App 10.0.5
Microsoft.NETCore.App 10.0.5
```

## Steps to reproduce

1. macOS 26 Tahoe on Apple Silicon, with IPv6 enabled (default).
2. Install .NET 10 SDK via Homebrew.
3. Create any project with a NuGet dependency.
4. Run `dotnet restore`.

Result: `NU1301` / `Broken pipe` as shown above.

## Key observations

- **`curl https://api.nuget.org/v3/index.json` works fine** from the same machine — `curl` uses Happy Eyeballs and falls back to IPv4 quickly.
- **`api.nuget.org` resolves through Azure Front Door** (Traffic Manager → Azure CDN → AFD). The IPv6 endpoint appears to reject or drop the TLS handshake initiated by `SocketsHttpHandler`.
- The issue is **not specific to NuGet** — it affects any HTTPS request made by `HttpClient`/`SocketsHttpHandler` that goes over IPv6 to this (and possibly other) Azure Front Door endpoints.

## Workaround

Setting the following environment variable forces `SocketsHttpHandler` to use IPv4 only, which resolves the issue completely:

```bash
export DOTNET_SYSTEM_NET_DISABLEIPV6=1
```

After setting this, `dotnet restore`, `dotnet add package`, and all other NuGet operations work correctly against `api.nuget.org`.

## Expected behavior

`SocketsHttpHandler` should either:
1. Successfully complete the TLS handshake over IPv6, or
2. Implement Happy Eyeballs (RFC 8305) to fall back to IPv4 when IPv6 fails, similar to how `curl` and browsers handle this transparently.

## Possible area

`System.Net.Http` — `SocketsHttpHandler` IPv6 + TLS on macOS with Apple Silicon.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.