-
Notifications
You must be signed in to change notification settings - Fork 28.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Happy Eyeballs support (address IPv6 issues in Node 17) #41625
Comments
I agree Node.js would benefit having this built-in. Is this something you'd be interested in working on @andreialecu? |
I am not sure what subsystem this would fit into. It seems that Happy Eyeballs not only applies to HTTP ( |
There's a writeup on how this is implemented in OSX here by an Apple engineer: https://mailarchive.ietf.org/arch/msg/v6ops/DYiI9v_O66RNbMJsx0NsatFkubQ
There's also an official RFC at: https://datatracker.ietf.org/doc/html/rfc8305 Since it deals with SYN packets, I'm not sure if this can be implemented in JS land or it needs to touch the C++ networking layer. I'm not familiar at all with nodejs networking internals. |
Yes, I believe it should go into Happy Eyeballs with UDP being connectionless is a bit more complicated. |
Mostly, yes, at least by default.
I am wondering how much complexity we can justify just to work around broken IPv6 stacks. The algorithms seem useful even beyond IPv6 compatibility, but so far I have no idea how we could implement this. We probably cannot do this for all TCP connections, at least not by default. We could maybe add an option to |
Why not? If I am not wrong this is the default for all Happy Eyeballs implementations. Though it uses some kind of cache. |
That statement is probably not factual. At least not at scale. Even if 1% of users are affected, depending on the number of users, that can add up quite a bit. Reddit has recently disabled IPv6 due to issues they were having: Also their Android app does not implement Happy Eyeballs, and here's a report specifically pinpointing this to be the problem: There's also a huge thread here: aws-amplify/amplify-js#5539 about an Android only issue that I was also running into, and which was specifically about Happy Eyeballs. Additionally, there are many other threads in other JS ecosystems related to Happy Eyeballs: facebook/react-native#29608 (comment) There are tons of reports still popping up. And it goes unreported most of the time, because it's very random and pretty much unreproducible since it's hard to actually pin it down to IPv6 being the culprit. |
@andreialecu Don't get me wrong, I am not saying there are no issues. I frequently run into some myself. That was just me quoting Wikipedia. IPv6 is older than myself and I really wish we didn't have to worry about broken IPv6 stacks at this point 😄 Either way, as I said in my last comment, someone would probably have to implement this in |
Perhaps this might help with that: https://github.com/shtrom/happy-eyeballs-c |
Not necessary, just call |
My understanding was that libuv might establish multiple connections in that case, whereas the algorithm above only sends SYNs until one receives a reply. Maybe that's wrong, or maybe establishing connections isn't that bad. |
You |
There has been no activity on this feature request for 5 months and it is unlikely to be implemented. It will be closed 6 months after the last non-automated comment. For more information on how the project manages feature requests, please consult the feature request management document. |
While Reddit is still in a staged rollout of IPv6, they've already published about implementing Happy Eyeballs on Android: https://www.reddit.com/r/RedditEng/comments/v1upr8/ipv6_support_on_android/ |
cc @nodejs/tsc this might be something we should look to implement before v18 hits LTS. |
+1 this seems to be directly affecting undici / undici-fetch. It would be nice to not have that baked into v18 LTS 😊 |
My team and I have been bitten by this issue (specifically with regard to localhost). Big +1 for fixing it and backporting the fix. |
I believe 3rd party package maintainers will realize they have to listen on |
How did you solve this? GitHub runners do not support IPv6 and I cannot use I tried the following but it did not solve it: import dns from 'dns';
dns.setDefaultResultOrder('ipv4first'); |
@undergroundwires which NodeJS version are you using. |
Thank you @treysis for showing interest. First I tested with latest 18 ( It fails specifically on Related issue for |
@undergroundwires does your host support IPv4? Or is it running on IPv6-only AWS? |
I created a repository to reproduce this in as minimal way as possible: https://github.com/undergroundwires/node-fetch-ipv6 I run fetch on using I realize that the first two requests are successful, I start getting the error after the second or third one. See the test: test file Second test (
|
This commit introduces the `force-ipv4` GitHub action to address connectivity issues caused by the lack of IPv6 support in GitHub runners. Details: - actions/runner#3138 - actions/runner-images#668 This change solves connection problems when Node's `fetch` API fails due to `UND_ERR_CONNECT_TIMEOUT` errors. Details: - actions/runner-images#9540 - actions/runner#3213 This action disables IPv6 at the system level, ensuring all outging requests use IPv4. Resolving connectivity issues when running external URL checks and Docker build checks. This solution is a temporary workaround until GitHub runners support IPv6 or Node `fetch` API has a working solution such as Happy Eyeball. Detais: - nodejs/node#41625 - nodejs/undici#1531
Here's my workaround (open-source and documented) that I hope that can help you too:
After days of research and trial/error, this is how I got this working:
Related commit introducing this fix: undergroundwires/privacy.sexy@52fadcd |
This commit upgrades Node.js version to v20.x in CI/CD environment. Previously used Node 18.x is moving towards end-of-life, with a planned date of 2025-04-30. In contrast, Node 20.x has been offering long-term support (LTS) since 2023-10-24. This makes Node 20.x a stable and recommended version for production environments. This commit also configures `actions/setup-node` with the `check-latest` flag to always use the latest Node 20.x version, keeping CI/CD setup up-to-date with minimal maintenance. Details: - actions/setup-node#165 - actions/setup-node#160 Using Node 20.x in CI/CD environments provides better compatibility with Electron v29.0 which moves to Node 20.x. Details: - electron/electron#40343 This upgrade improves network connection handling in CI/CD pipelines (where issues occur due to GitHub runners not supporting IPv6). Details: - actions/runner#3138 - actions/runner-images#668 - actions/runner#3213 - actions/runner-images#9540 Node 20.x adopts the Happy Eyeballs algorithm for improved IPv6 connectivity. - nodejs/node#40702 - nodejs/node#41625 - nodejs/node#44731 This mitigates issues like `UND_ERR_CONNECT_TIMEOUT` and localhost DNS resolution in CI/CD environments: Details: - nodejs/node#40537 - actions/runner#3213 - actions/runner-images#9540 Node 20 introduces `setDefaultAutoSelectFamily`, a global function from Node 19.4.0, enabling better IPv4 support, especially in environments with limited or problematic IPv6 support. Details: - nodejs/node#45777 Node 20.x defaults to the new `autoSelectFamily`, improving network connection reliability in GitHub runners lacking full IPv6 support. Details: - nodejs/node#46790
This commit upgrades Node.js version to v20.x in CI/CD environment. Previously used Node 18.x is moving towards end-of-life, with a planned date of 2025-04-30. In contrast, Node 20.x has been offering long-term support (LTS) since 2023-10-24. This makes Node 20.x a stable and recommended version for production environments. This commit also configures `actions/setup-node` with the `check-latest` flag to always use the latest Node 20.x version, keeping CI/CD setup up-to-date with minimal maintenance. Details: - actions/setup-node#165 - actions/setup-node#160 Using Node 20.x in CI/CD environments provides better compatibility with Electron v29.0 which moves to Node 20.x. Details: - electron/electron#40343 This upgrade improves network connection handling in CI/CD pipelines (where issues occur due to GitHub runners not supporting IPv6). Details: - actions/runner#3138 - actions/runner-images#668 - actions/runner#3213 - actions/runner-images#9540 Node 20.x adopts the Happy Eyeballs algorithm for improved IPv6 connectivity. - nodejs/node#40702 - nodejs/node#41625 - nodejs/node#44731 This mitigates issues like `UND_ERR_CONNECT_TIMEOUT` and localhost DNS resolution in CI/CD environments: Details: - nodejs/node#40537 - actions/runner#3213 - actions/runner-images#9540 Node 20 introduces `setDefaultAutoSelectFamily`, a global function from Node 19.4.0, enabling better IPv4 support, especially in environments with limited or problematic IPv6 support. Details: - nodejs/node#45777 Node 20.x defaults to the new `autoSelectFamily`, improving network connection reliability in GitHub runners lacking full IPv6 support. Details: - nodejs/node#46790
What is the problem this feature will solve?
It appears that node 17 has merged this PR: #39987 which may result in IPv6 addresses being sorted first.
As per an answer in this reddit thread from @treysis: https://www.reddit.com/r/ipv6/comments/qbr8jc/comment/hhmg7uz/?context=3 it appears that Happy Eyeballs is not implemented however.
The lack of Happy Eyeballs support can result in connections failing. In particular, there are a lot of data points related to similar support lacking from the OkHttp library which is used heavily on Android and results in connectivity issues for a relatively big number of users. Ref: square/okhttp#506 (comment)
The problem is that consumer routers sometimes glitch out on IPv6.
A router I manage in one particular location, which is a consumer grade TP-Link router, will routinely hang on IPv6 connections about once per month, until it is restarted. More on this here: square/okhttp#6954 (comment)
I have noticed that Node 17 will then pretty much hang on outgoing connections for up to one minute before eventually being able to connect. Restarting the router resolves the issue.
What is the feature you are proposing to solve the problem?
Implement the Happy Eyeballs algorithm.
What alternatives have you considered?
There is an user-land patch here: https://www.npmjs.com/package/happy-eyeballs by @zwhitchcox which might help as a workaround.
The text was updated successfully, but these errors were encountered: