IPGlobalProperties.GetActiveTcpListeners() returns zero listeners on macOS 27
- Dominant language
- C#
- Stars
- 18.3k
- Forks
- 5.6k
- PR merge metrics
- PR metrics pending
Description
### Description
`IPGlobalProperties.GetActiveTcpListeners()` returns zero listeners on macOS 27.
This looks like the macOS `sysctl` PCB-list path returning nothing, plausibly a struct or ABI change in macOS 27. That attribution is inference from how the API is implemented on macOS, not something observed directly. Reproduces on .NET 8.0.421 and on the .NET 10.0.12 runtime.
Real-world impact: tooling that discovers local services this way silently finds nothing rather than failing loudly.
### Reproduction Steps
1. Start any process that listens on a TCP port. In my case an ASP.NET Core app on `127.0.0.1:5005`, but `python3 -m http.server 5005` behaves the same.
2. Run:
```csharp
var l = System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners();
Console.WriteLine($"listeners: {l.Length}");
```
Output:
```shell
listeners: 0
```
3. Confirm that the operating system does list the socket at the same moment:
```shell
$ lsof -nP -iTCP:5005
Altinn.Ap 45270 ... TCP 127.0.0.1:5005 (LISTEN)
$ netstat -an -p tcp | grep 5005
tcp4 0 0 127.0.0.1.5005 *.* LISTEN
```
4. Run the same binary against the .NET 10 runtime:
```shell
$ DOTNET_ROLL_FORWARD=LatestMajor dotnet bin/Debug/net8.0/tcpprobe.dll
listeners: 0
```
### Expected behavior
The machine's listening TCP endpoints, including 127.0.0.1:5005
### Actual behavior
`listeners: 0`
### Regression?
I don't know. I never ran `GetActiveTcpListeners()` on macOS 26, so all I can say is that the same SDK version returns zero on macOS 27 while `lsof` and `netstat` both see the listener.
### Known Workarounds
Read the listener list from the operating system instead:
- Parse `netstat -anv -p tcp` and filter on `LISTEN`. Note that on macOS 27 the verbose output merges the former `pid` and `epid` columns into a single `process:pid` field whose value can contain spaces, for example `Code Helper:7260`, so splitting on whitespace by field index no longer works for the process part.
- P/Invoke `libproc` (`proc_listpids` plus `proc_pidfdinfo`), which returns ports and owning PIDs directly.
- Shell out to `lsof -nP -iTCP -sTCP:LISTEN`.
### Configuration
- .NET SDK 8.0.421, and the .NET 10.0.12 runtime via `DOTNET_ROLL_FORWARD=LatestMajor`
- macOS 27.0 (Golden Gate), arm64, Apple Silicon
- Not specific to any one application. The listening socket in the repro was an ASP.NET Core app, but any listener shows the same result.
### Other information
This surfaced while debugging a local development tool that could no longer find a running app after a macOS 26 to 27 upgrade. That tool uses its own `netstat` parsing rather than this API, so the two failures are independent, but both point at port enumeration on macOS 27 as the common factor.
Contributor guide
Research direction
Start at IPGlobalProperties.GetActiveTcpListeners() and the macOS sysctl PCB-list path used by its implementation. Reproduce with a listener on 127.0.0.1:5005 and compare the API result with lsof or netstat. Done means the API reports the machine's active TCP listening endpoints on macOS 27.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp, macos
- Domain
- networking, operating-systems
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100