Skip to content

macOS: EHOSTUNREACH / FailedToOpenSocket when VPN Network Extension leaves orphaned virtual interfaces #26807

Closed as not planned

Description

@venku122

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

  1. Install a VPN with a Network Extension (e.g., ProtonVPN, Mullvad)
  2. Connect and disconnect the VPN
  3. Configure OpenCode with a custom provider pointing to a LAN IP
  4. Run opencode -m provider/model "hello"

Expected behavior

OpenCode should either:

  • Connect successfully via the physical network interface, or
  • Provide a clear error message with troubleshooting steps when EHOSTUNREACH is detected while curl succeeds

Suggested improvements

  1. Better error diagnostics: When OpenCode gets FailedToOpenSocket / EHOSTUNREACH, log whether curl can reach the same URL. If curl succeeds but Node.js fetch fails, surface a macOS-specific troubleshooting hint about VPN Network Extensions and suggest a reboot.

  2. curl fallback transport: Offer a config option to use curl as the HTTP transport (via subprocess) for providers that fail with Node.js's fetch. curl consistently bypasses per-application NE filters on macOS.

  3. Connection validation: Add a pre-flight check that verifies TCP connectivity to the provider's base URL using a method that's not affected by NE filters (e.g., a quick curl -m 5 call), and surface a clear warning if the check fails.

Environment

  • macOS 26.4 (Sequoia)
  • OpenCode 1.14.47
  • Custom provider: @ai-sdk/openai-compatible with baseURL: http://192.168.1.249:18100/v1
  • VPN: ProtonVPN (WireGuard Network Extension)

Activity

  1. github-actions commented on May 11, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

  2. venku122 commented on May 11, 2026

    @venku122
    Author

    This was a tricky issue. I am running Qwen-3-Coder-Next on a machine on my LAN. It was working fine on WSL2 under windows but would constantly error on my Macbook. After poking at the server and client ends I was able to narrow it down to ProtonVPN and these interfaces.
    Uninstalling and restarting the machine eventually resolved it.

    Image
  3. github-actions commented on Jul 11, 2026

    @github-actions
    Contributor

    To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions