NVIDIA / NVIDIA/Personal-AI-Router
[Bug]: macOS M4 cannot obtain Local Network permission (no prompt, missing NSLocalNetworkUsageDescription) — cross-host discovery and EC-peer routing fail
@Noah-Tervalon-Nvidia đang làm issue này rồi.
Từ ngày 11/9/2026.
- Ngôn ngữ chính
- Go
- Star
- 1.4k
- Fork
- 250
- Merge trung bình
- 23 giờ 27 phút
- Pull request đã merge (30 ngày)
- 1
Mô tả
PAIR version
v0.1.1 (both nodes), from the official release assets:
- Linux amd64
.deb(devbox, x86_64) - macOS arm64
.dmg(Apple M4)
Host OS (exact)
- macOS node: macOS 27.0 (build 26A5388g), Apple M4, 16 GB
- Linux node: Omarchy 4.0.2 (
/etc/os-release:ID=omarchy,VERSION_ID=4.0.2), x86_64, NVIDIA RTX 2000 Ada (8 GB)
Summary
macOS M4 node cannot obtain Local Network permission, so cross-host discovery and EC-peer registration fail. The shipped macOS bundle lacks NSLocalNetworkUsageDescription, and no permission prompt ever appears on this macOS version.
Verified (2026-09-04): plist keys alone are insufficient on macOS 27.0
We rebuilt PAIR from source applying the exact config fix from the (now-closed)
PR #12: added NSLocalNetworkUsageDescription and
NSBonjourServices: ["_nvpair-node._tcp"] to mac.extendInfo in
electron-builder.config.ts, built all modular Go binaries for darwin/arm64,
and produced a fresh .app whose Info.plist verifiably contains both keys.
Launched under the original com.nvidia.nvpair identity:
- No Local Network consent prompt appears.
- mDNS multicast still fails identically:
sendto: no route to hoston en0. - Unified logs show the LocalNetwork subsystem finding the bundle by PID/UUID
each attempt, but no prompt and no explicit verdict.
Conclusion: the two plist keys are necessary but not sufficient. Leading
hypothesis: PAIR's scanner sends raw UDP multicast via Go's net package,
which does not traverse the API path (Bonjour/DNSService) that macOS TCC Local
Network enforcement associates with the declared NSBonjourServices — so no
consent is ever solicited. A fix likely needs the discovery layer to use the
system Bonjour API, not just the plist declaration.
What works (verified)
- Single-node routing on the Linux node: model pull + chat through PAIR's proxy (11434) with Jobs telemetry (devbox→devbox).
- Cluster membership via manual Add-node-by-IP: both nodes appear as
memberinmembers.jsonwith the sameclusterId. - TCP connectivity between nodes after opening firewall ports.
- Privileged firewall helper (
com.nvidia.nvpair.helper) loads from the signed bundle once approved in Login Items.
What fails (observed)
-
Mac node-scanner mDNS multicast blocked. Log repeats every ~5 s:
[nvpair-node-scanner] WARN mdns send: query did not leave any interface service=_nvpair-node._tcp failed=2 errors="en0 write: write udp4 192.168.1.42:...->224.0.0.251:5353: sendto: no route to host"A direct Python UDP multicast from Terminal to
224.0.0.251:5353succeeds on the same host — so the block is app-specific. -
No Local Network permission prompt ever appears on macOS for
com.nvidia.nvpair, and the app never appears under System Settings → Privacy & Security → Local Network.NSLocalNetworkUsageDescriptionis absent from the shippedInfo.plist(only legacyNSAllowsLocalNetworkingis present). macOS will not show the consent prompt or list the app without that key. -
Patched-copy test: inconclusive. Added
NSLocalNetworkUsageDescription, re-signed (ad-hoc, then Apple Development identity), reset TCC (tccutil reset All com.nvidia.nvpair), launched from Finder/LaunchServices — still no prompt, multicast still denied. Caveat: this copy was made by editing only the outerInfo.plist/CFBundleIdentifier; nested Mach-O binaries retained the original team/signing identity. This test did not establish a fresh TCC identity, so it cannot determine whether the key alone fixes prompting. -
Cross-node engine-control fails. Both nodes log
node X is not a discovered ec peer(engine-managerremote.go). Manual node admission creates cluster membership but does not populate the EC peer directory, which is fed only from discovery relay snapshots. -
Cross-node model routing fails. Devbox PAIR proxy returns
no available node advertises the requested modelfor a Mac-only model; Mac proxy likewise for a devbox-only model. Manual-node model probing appears limited to plaintext engine endpoints, which PAIR's proxy rejects for remote peers (loopback-only, mTLS ingress required).
Expected behavior
- macOS node should be able to receive Local Network permission (prompt appears; app listed in Privacy → Local Network), enabling mDNS discovery of
_nvpair-node._tcp. - With mDNS working, discovery snapshots should populate the EC peer directory so cross-node engine status and routing work, as they do for same-LAN Linux nodes.
Suggested fix (actionable)
- Add
NSLocalNetworkUsageDescriptionto the macOSInfo.plistand
_nvpair-node._tcpunderNSBonjourServicesinmac.extendInfo
(electron-builder.config.ts) — done in the closed PR #12 and verified in a
source rebuild, but this alone does not restore the prompt. - Migrate the discovery layer's mDNS from raw Go
netUDP sockets to the
system Bonjour API (DNSServiceBrowse/DNSServiceRegister), which is the
path macOS TCC associates with the declared Bonjour service and uses to
solicit Local Network consent. - Verify the notarized build's first-use prompt on a clean macOS install.
Environment notes
tccutil resetfor LocalNetwork service names returns RC 70 on this macOS version ("unsupported service");tccutil reset All com.nvidia.nvpairsucceeds.- Tailscale on/off both tested — not the cause.
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Đánh giá
Issue này chưa được đánh giá.