Skip to content

fix(net): force IPv4 and disable Happy Eyeballs in Node entrypoints#2731

Open
georgemunyoro wants to merge 1 commit into
mainfrom
posthog-code/fix-connectivity-probe-tailscale
Open

fix(net): force IPv4 and disable Happy Eyeballs in Node entrypoints#2731
georgemunyoro wants to merge 1 commit into
mainfrom
posthog-code/fix-connectivity-probe-tailscale

Conversation

@georgemunyoro

@georgemunyoro georgemunyoro commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Problem

Connections to us.posthog.com fail when Tailscale is enabled. The root cause was traced to IPv6 EHOSTUNREACH errors during Node fetch. PostHog's many-address ELB times out the connect when IPv6 is unreachable (e.g. via Tailscale), because Node's "Happy Eyeballs" family racing abandons each IPv4 attempt before it can complete. Setting ipv4first alone is not sufficient to resolve this.

Reproduction

With Tailscale enabled, attempt to log in (against us.posthog.comnot a local localhost PostHog, which is loopback and unaffected). The login fails because the main-process OAuth token call is a Node fetch to PostHog's ELB, which times out. The same failure then affects the agent, auth-proxy and MCP proxy (all outbound Node fetch from the workspace-server child), making the app effectively unusable.

The underlying network failure can be reproduced directly:

# With Tailscale enabled — fails with AggregateError [ETIMEDOUT] after ~2s:
node -e '
const u="https://us.posthog.com/_health"; const t=Date.now();
fetch(u,{method:"HEAD",signal:AbortSignal.timeout(8000)})
  .then(r=>console.log("OK",r.status,Date.now()-t+"ms"))
  .catch(e=>console.log("FAIL",e.name,Date.now()-t+"ms"));'

# The same call succeeds once family autoselection is disabled (the fix in this PR):
node --no-network-family-autoselection --dns-result-order=ipv4first -e '
const u="https://us.posthog.com/_health"; const t=Date.now();
fetch(u,{method:"HEAD",signal:AbortSignal.timeout(8000)})
  .then(r=>console.log("OK",r.status,Date.now()-t+"ms"))
  .catch(e=>console.log("FAIL",e.name,Date.now()-t+"ms"));'

Changes

  • apps/code/src/main/bootstrap.ts: Disable Happy Eyeballs via net.setDefaultAutoSelectFamily(false) in the Electron main bootstrap, complementing the existing dns.setDefaultResultOrder(\"ipv4first\") call. Added an explanatory comment about why ipv4first alone is insufficient.
  • packages/workspace-server/src/serve.ts: Mirror the same network configuration (dns.setDefaultResultOrder(\"ipv4first\") + net.setDefaultAutoSelectFamily(false)) in the workspace-server entrypoint, since this child process makes all outbound HTTPS calls to PostHog and the gateway.

TL;DR Force IPv4 and disable Node's Happy Eyeballs family selection in both the Electron main process and the workspace-server entrypoint, fixing connection timeouts to PostHog's ELB when IPv6 is unreachable (e.g. under Tailscale).

How did you test this?

  • Reproduced the failure by logging in with Tailscale enabled against us.posthog.com (see Reproduction above) — login failed with IPv6 EHOSTUNREACH / ETIMEDOUT errors before the fix and succeeds after it.
  • Confirmed the underlying node -e repro fails with default settings and succeeds with --no-network-family-autoselection --dns-result-order=ipv4first.
  • Typecheck + lint pass; connectivity service unit tests pass (16/16).

Automatic notifications

  • Publish to changelog?
  • Alert Sales and Marketing teams?

Created with PostHog Code

PostHog's API and LLM gateway resolve to a many-address AWS ELB (~8 IPv4
+ ~8 IPv6). When IPv6 is unreachable (e.g. under Tailscale), Node's
default "Happy Eyeballs" (autoSelectFamily) races families with a short
per-attempt timeout and abandons each IPv4 attempt before the ELB connect
completes, timing out the whole connection — even though a plain IPv4
connect succeeds. This made the app unusable on Tailscale: the agent,
auth-proxy, MCP proxy and OAuth all make Node fetches that hung.

Set dns.setDefaultResultOrder("ipv4first") + net.setDefaultAutoSelectFamily(false)
in both Node entrypoints (workspace-server child and the Electron main
process). ipv4first alone is insufficient; the family racing must be off.

Generated-By: PostHog Code
Task-Id: 3b32c227-2ae9-4681-9617-6e6fa0cd0de9
@github-actions

github-actions Bot commented Jun 17, 2026

Copy link
Copy Markdown

React Doctor found no issues in the changed files. 🎉

Reviewed by React Doctor for commit 7d722ea.

@greptile-apps

greptile-apps Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Reviews (1): Last reviewed commit: "fix(net): force IPv4 and disable Happy E..." | Re-trigger Greptile

@georgemunyoro georgemunyoro marked this pull request as ready for review June 17, 2026 13:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant