[Bug]: Browser downloads time out (30000ms) on dual-stack/VPN environments due to broken Happy Eyeballs in dualStackLookup
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 68/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- node.js, typescript
- Domain
- networking
Research direction
Start in packages/utils/src/network.ts, reading dualStackLookup and the httpRequest happyEyeballsOptions described in the report. Reproduce with npx playwright install firefox on a dual-stack or VPN environment where IPv6 is unrouted, then verify that the downloader falls back to IPv4 promptly and respects the relevant family or DNS options instead of waiting 30 seconds.
Written by the indexing model from the issue text.
Description
Version
1.63.0
Steps to Reproduce
- Connect to any network or VPN interface that has a local IPv6 address configured but does not route public IPv6 internet traffic (or where public IPv6 is black-holed).
- Run
npx playwright install firefox(or any non-cached browser binary). - Observe repeated 30-second timeouts:
Downloading Firefox 155.0 (playwright firefox v1543) from https://cdn.playwright.dev/dbazure/download/playwright/builds/firefox/1543/firefox-mac-arm64.zip
Error: Request to https://cdn.playwright.dev/dbazure/download/playwright/builds/firefox/1543/firefox-mac-arm64.zip timed out after 30000ms
at ClientRequest.<anonymous> (.../node_modules/playwright-core/lib/coreBundle.js:8793:15)
at TLSSocket.emitRequestTimeout (node:_http_client:1122:9)
...
Failed to install browsers
Error: Failed to download Firefox 155.0 (playwright firefox v1543), caused by
Error: Download failure, code=1
Expected behavior
Playwright's downloader should either:
- Supply
all: truetodualStackLookupso Node's nativeautoSelectFamilycan race IPv6 and IPv4 and fall back to IPv4 within milliseconds when IPv6 connection attempts stall. - Respect
options.family/ Node's--dns-result-order=ipv4first. - Or fall back to IPv4 upon socket connection timeout rather than failing the entire download attempt.
Actual behavior
Running playwright install fails with repeated Request to https://cdn.playwright.dev/... timed out after 30000ms when connected to a dual-stack or corporate VPN network where an IPv6 address is bound to an interface (e.g., ULA fc00::), but public IPv6 internet traffic is unrouted or dropped.
While tools implementing standard Happy Eyeballs (RFC 8305) like curl and web browsers fall back to IPv4 within 250–300ms, Playwright's downloader hangs for the full 30-second socket timeout across all retry attempts.
Additional context
Root Cause Analysis
In packages/utils/src/network.ts:
-
dualStackLookuphardcodes IPv6 ahead of IPv4:dualStackLookup = (hostname, options, callback) => { const families = options.family === 4 || options.family === 6 ? [options.family] : [6, 4]; // ... if (options.all) callback(null, addresses); else callback(null, addresses[0].address, addresses[0].family); }; -
When
httpRequest()useshappyEyeballsOptions:happyEyeballsOptions = { lookup: dualStackLookup, autoSelectFamily: true, autoSelectFamilyAttemptTimeout: Math.max(5e3, net.getDefaultAutoSelectFamilyAttemptTimeout()) };Because
httpRequestdoes not passall: trueto the lookup options,dualStackLookuponly returnsaddresses[0](the IPv6 address). -
Node's
autoSelectFamily: truealgorithm requires multiple addresses (oroptions.all: true) to race or fall back between IPv6 and IPv4. Because only a single IPv6 address is supplied tocallback(), Node has no alternative address to fall back to. -
When Node attempts to connect to
2603:1061:14:72::1, the SYN packets are silently dropped by the unrouted network, hanging untilNET_DEFAULT_TIMEOUT(30000ms) fires. -
Furthermore,
NODE_OPTIONS="--dns-result-order=ipv4first"has no effect becausefamilies = [6, 4]is hardcoded regardless of the runtime's DNS configuration.
Environment
System:
OS: macOS 26.6.2
CPU: (12) arm64 Apple M2 Max
Memory: 81.27 MB / 32.00 GB
Binaries:
Node: 24.11.0 - /Users/{username}/.local/share/mise/installs/node/24.11.0/bin/node
Yarn: 4.18.0 - /Users/{username}/.local/share/mise/installs/node/24.11.0/bin/yarn
npm: 11.6.1 - /Users/{username}/.local/share/mise/installs/node/24.11.0/bin/npm
IDEs:
VSCode: 1.138.0 - /Applications/Visual Studio Code.app/Contents/Resources/app/bin/code
Languages:
Bash: 3.2.57 - /bin/bash
npmPackages:
@playwright/test: ^1.63.0 => 1.63.0
playwright: ^1.63.0 => 1.63.0
- Dominant language
- TypeScript
- Stars
- 96.4k
- Forks
- 6.5k
- Avg merge
- 1d 7h
- Merged PRs (30d)
- 170
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from microsoft/playwright
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
microsoft/playwright#42804 ·
-
[CLI]: skill doesn't warn that a generated locator is only unique against the current page state Openneeds-triage-mac
Difficulty 1/5 Under an hour Newbie friendliness 91/100
microsoft/playwright#42790 · 1 comment ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
microsoft/playwright#42782 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
microsoft/playwright#42745 · 1 comment ·
-
[Bug]: MCP idle timeout closes the browser during a tool call that outlasts it, failing that call Open
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
microsoft/playwright#42693 · 1 comment ·
All issues in microsoft/playwright
Similar issues
-
comp/dashboard P3 type/bug
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
NousResearch/hermes-agent#117722 ·
-
clawsweeper:fix-shape-clear clawsweeper:queueable-fix clawsweeper:source-repro impact:ux-friction issue-rating: 🦞 diamond lobster no-stale P3
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
community first-timers-only good first issue hacktoberfest help wanted low hanging fruit up-for-grabs
Difficulty 1/5 Under an hour Newbie friendliness 76/100
-
code-quality refactoring
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
github/gh-aw-firewall#8816 ·
-
integration:quickjs org:external priority:backlog topic:code-interpreter topic:middleware type:feature
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
langchain-ai/deepagents#6450 ·