DEV Community

linou518
linou518

Posted on

When macOS 26 (Tahoe) Blocked Python Socket Connections — and How LaunchDaemon Fixed It

When macOS 26 (Tahoe) Blocked Python Socket Connections — and How LaunchDaemon Fixed It

TL;DR

On macOS 26 (Tahoe), WebSocket connections from Homebrew-installed Python were failing with errno 65 (No route to host). curl worked fine, but Python kept failing. The culprit: TCC (Transparency, Consent, and Control). The fix: switching from LaunchAgent to LaunchDaemon.


Background

We were building an automated setup script to install OpenClaw (an AI assistant framework) on refurbished Mac minis (M1, macOS 26.0.1 Tahoe) for resale. A Python script running as a LINE Bridge — connecting to a WebSocket relay server — was registered as a LaunchAgent, but the Gateway refused to start.

The logs showed:

socket.connect_ex(('192.168.x.x', 3500)) → errno 65: No route to host
Enter fullscreen mode Exit fullscreen mode

The target was another host on the same LAN. Ping worked. curl worked. But Python failed consistently.


Debugging

Everything We Checked First (All Wrong)

1. IP/Port problem?

ping 192.168.x.x        # OK
curl http://192.168.x.x:3500  # OK
nc -zv 192.168.x.x 3500       # OK
Enter fullscreen mode Exit fullscreen mode

All passed. The problem was isolated to Python.

2. Hairpin NAT?

We were initially connecting to an external domain (wss://linebot.techsfree.com). Some routers block connections from inside the LAN to the router's own external IP (no hairpin NAT support). That was a real issue — we switched to the internal IP — but the error persisted.

3. Firewall?

sudo /usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate
# Firewall is disabled.
Enter fullscreen mode Exit fullscreen mode

Nope.

The Real Culprit: TCC

Running sudo python3 script.py directly worked. Running via LaunchAgent (user-level) failed. Root succeeded.

macOS TCC (Transparency, Consent, and Control) manages third-party app access to system resources. On macOS 26 Tahoe, Homebrew-installed Python became subject to TCC checks for network connections when launched from user-space (LaunchAgent).

Verification:

# Via LaunchAgent (user-level) → FAIL
launchctl load ~/Library/LaunchAgents/com.openclaw.linebridge.plist
# → errno 65: No route to host

# Direct sudo execution → OK
sudo /opt/homebrew/bin/python3 line_bridge_v2.py
# → Connected to relay server ✓

# subprocess.run(['curl', ...]) → OK
# curl is a system binary and bypasses TCC
Enter fullscreen mode Exit fullscreen mode

The Fix: Promote to LaunchDaemon

LaunchAgents (~/Library/LaunchAgents/) run in user space. LaunchDaemons (/Library/LaunchDaemons/) run at the system level (root) and bypass TCC.

Before (LaunchAgent):

<!-- ~/Library/LaunchAgents/com.openclaw.linebridge.plist -->
<key>Label</key>
<string>com.openclaw.linebridge</string>
Enter fullscreen mode Exit fullscreen mode

After (LaunchDaemon):

<!-- /Library/LaunchDaemons/com.openclaw.linebridge.plist -->
<key>Label</key>
<string>com.openclaw.linebridge</string>
<key>UserName</key>
<string>openclaw</string>  <!-- Runs as system daemon but with user file access -->
Enter fullscreen mode Exit fullscreen mode

The UserName key lets you run as a root-level daemon while still reading/writing files as the openclaw user.

# Register
sudo launchctl bootstrap system /Library/LaunchDaemons/com.openclaw.linebridge.plist
sudo launchctl enable system/com.openclaw.linebridge
Enter fullscreen mode Exit fullscreen mode

Result: Connected to relay server ✓ — fixed immediately.


macOS 26 TCC Summary

Execution method TCC restricted Notes
System binaries (curl, etc.) No Always works
sudo python3 No Root bypasses TCC
LaunchAgent + Homebrew Python Yes errno 65
LaunchDaemon + UserName key No ✅ Recommended
subprocess.run(['curl', ...]) No Workaround via system binary

macOS 26 has significantly tightened security. Scripts that worked fine on earlier versions may break — especially resident daemons + third-party runtimes + network connections.


Side Note: Mac Mini Factory Automation

This issue appeared while building a product: refurbished Mac minis pre-installed with OpenClaw, sold as AI assistants.

Unlike GMK Ubuntu units (where Clonezilla image cloning works), Apple Silicon + SIP makes Mac imaging impossible. Instead, we built a set of automation scripts:

  • factory-setup-mac.sh — Full automated install (~15 min)
  • per-unit-setup-mac.sh — Per-unit token assignment (5 sec)
  • factory-qc-mac.sh — Pre-ship QC (22-item checklist)
  • factory-clean-mac.sh — Pre-ship cleanup

The TCC fix is now built into factory-setup-mac.sh — future units will automatically register the LINE Bridge as a LaunchDaemon.

Top comments (0)