SocketsHttpHandler TLS handshake fails with 'Broken pipe' over IPv6 on macOS 26 Tahoe (.NET 10)
- 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
Assessment
This issue has not been assessed yet.