Describe the bug
OpenCode fails to connect to custom providers on macOS when a VPN application (ProtonVPN, Mullvad, etc.) has installed a Network Extension that leaves behind orphaned virtual interfaces after disconnection. The error logged is:
AI_APICallError → FailedToOpenSocket (EHOSTUNREACH)
The connection succeeds via curl, ping, and nc, but Node.js fetch and raw TCP sockets from the system Node.js and Python all fail with EHOSTUNREACH. The opencode models command may work (GET requests) while opencode run hangs or fails (POST requests with large payloads).
Root Cause
VPN Network Extensions (ProtonVPN WireGuard, Mullvad, etc.) create virtual tunnel interfaces (ipsec0, ipsec1, etc.) that claim the same subnet as the physical LAN interface. When the VPN disconnects, these interfaces can remain UP with stale IPs, causing the macOS kernel to route connect() syscalls from certain processes into the dead interface.
In this specific case:
ipsec1 and ipsec2 persisted with config 192.168.1.174 → 192.168.1.174 netmask 0xffffff00
- Default routes pointed at these dead interfaces
- Only
curl, nc, ping worked -- Node.js/Python got EHOSTUNREACH
To Reproduce
- Install a VPN with a Network Extension (e.g., ProtonVPN, Mullvad)
- Connect and disconnect the VPN
- Configure OpenCode with a custom provider pointing to a LAN IP
- Run
opencode -m provider/model "hello"
Expected behavior
OpenCode should either:
[Truncado — 2623 chars totais]
Describe the bug
OpenCode fails to connect to custom providers on macOS when a VPN application (ProtonVPN, Mullvad, etc.) has installed a Network Extension that leaves behind orphaned virtual interfaces after disconnection. The error logged is:
The connection succeeds via
curl,ping, andnc, but Node.js fetch and raw TCP sockets from the system Node.js and Python all fail withEHOSTUNREACH. Theopencode modelscommand may work (GET requests) whileopencode runhangs or fails (POST requests with large payloads).Root Cause
VPN Network Extensions (ProtonVPN WireGuard, Mullvad, etc.) create virtual tunnel interfaces (
ipsec0,ipsec1, etc.) that claim the same subnet as the physical LAN interface. When the VPN disconnects, these interfaces can remain UP with stale IPs, causing the macOS kernel to routeconnect()syscalls from certain processes into the dead interface.In this specific case:
ipsec1andipsec2persisted with config192.168.1.174 → 192.168.1.174 netmask 0xffffff00curl,nc,pingworked -- Node.js/Python gotEHOSTUNREACHTo Reproduce
opencode -m provider/model "hello"Expected behavior
OpenCode should either: