Tailscale’s macOS Network Extension silently breaks Rust binaries
If you’re running Tailscale on macOS and your Rust binary can’t connect to local network IPs — this is probably why.
The symptom
Any TCP connection from a Rust-compiled binary to a local IP (e.g. 10.0.0.167:7777) fails with:
No route to host (os error 65)
Meanwhile curl, python, nc all connect to the same address just fine. Same machine, same moment.
The cause
Tailscale’s macOS Network Extension (io.tailscale.ipn.macsys.network-extension) intercepts TCP connections from non-Apple-signed binaries. Apple’s own system tools are signed arm64e and bypass the extension entirely. Rust binaries compile to arm64 with ad-hoc signatures — so they get intercepted.
This happens below the application layer. It doesn’t matter what HTTP client you use or how you configure it.
What doesn’t work
I tried all of these — none had any effect:
reqwest::Client::builder().no_proxy()— problem is below app layerProxy::custom(|_| None)— same reasontailscale set --exit-node-allow-lan-access=true— no exit node configured, irrelevant- Binding the socket to en0’s local IP before connecting — still intercepted
- Even raw
libc::connect()from Rust fails while Python’ssocket.connect()succeeds simultaneously
Possible solutions
Still investigating, but the options are:
- Code-sign the binary with a real developer certificate (not ad-hoc)
- Local proxy relay — use socat or SSH tunnel (Apple-signed) to forward traffic
- Switch Tailscale to userspace networking mode instead of Network Extension
- Tailscale admin console — exclude local subnets from interception
NEFilterManagerAPI — programmatically request exclusion
You’re not alone
I searched around and found no one reporting this exact combination (Tailscale + Rust binary + local network), but there are two well-documented issues that likely overlap:
Tailscale routing bugs on macOS
- tailscale/tailscale#15366 — With an exit node active on macOS, local network access breaks even with “Allow Local Network Access” enabled. Tailscale installs incorrect routing rules. Still broken on macOS 26 Beta.
- tailscale/tailscale#1344 — Hosts on the same subnet become unreachable through Tailscale due to route priority: local subnet routes are narrower and win over Tailscale’s wider routes.
macOS Sequoia Local Network Privacy
Starting with macOS 15 Sequoia, Apple added a Local Network Privacy layer that silently blocks third-party binaries from accessing local network resources:
- Apple Developer Forums — Third-party binaries launched from launchd agents get denied local network access even after the user approves the privacy prompt. A known Sequoia bug.
- Mozilla Bug #1919889 — Firefox couldn’t access local network sites on Sequoia — same class of issue.
- Michael Tsai’s blog — Detailed roundup of developer reports on Sequoia’s Local Network Privacy silently denying permissions.
- Hackaday — macOS 15.1 forces application signing; ad-hoc signed binaries face stricter restrictions.
What this means
The root cause is likely one or both of these issues stacking:
- Tailscale installs broken routes for local subnets on macOS
- macOS Sequoia’s Local Network Privacy silently blocks ad-hoc signed binaries
It’s probably not just the Network Extension intercepting traffic — there may be an OS-level privacy gate involved too.
Takeaway
If you’re debugging “No route to host” errors that only affect your compiled binaries on macOS, check two things:
- Whether a Network Extension (Tailscale, Little Snitch, etc.) is intercepting your traffic
- Whether macOS Local Network Privacy is silently blocking your binary (System Settings > Privacy & Security > Local Network)
Tracking this at rararulab/rara#1023.