Skip to content
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

Cannot send outbound requests using node fetch, failing with IPv6 DNS error UND_ERR_CONNECT_TIMEOUT #9540

Closed
3 of 13 tasks
undergroundwires opened this issue Mar 20, 2024 · 5 comments

Comments

@undergroundwires
Copy link

Description

Sending more than one (sometimes two or three) requests using fetch results in DNS errors.

I get UND_ERR_CONNECT_TIMEOUT errors which is related to IPv6 issues in node.
Related issue for node: nodejs/node#41625,
Related issue for node fetch: nodejs/undic#1531
Related issue for GitHub runners not being able to do IPv6: #668, actions/runner#3138
image

Platforms affected

  • Azure DevOps
  • GitHub Actions - Standard Runners
  • GitHub Actions - Larger Runners

Runner images affected

  • Ubuntu 20.04
  • Ubuntu 22.04
  • macOS 11
  • macOS 12
  • macOS 13
  • macOS 13 Arm64
  • macOS 14
  • macOS 14 Arm64
  • Windows Server 2019
  • Windows Server 2022

Image version and build link

Failed build: https://github.com/undergroundwires/node-fetch-ipv6/actions/runs/8350276298

Is it regression?

Yes, successful build runs are old

Expected behavior

The requests are being sent fine, this was the case before.

Actual behavior

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 vite test runner on node and without any test runner. I get same results.
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 (multiple fetch in order) fails, and all run fine locally. I run tests on default GitHub runners using both latest node 20 and 18. I get same errors:

Repro steps

  1. Run the job from undergroundwires/node-fetch-ipv6
  2. Check output
@Alexey-Ayupov
Copy link
Collaborator

Hello @undergroundwires, do I understand correctly that you are trying to fetch using ipv6?

@undergroundwires
Copy link
Author

undergroundwires commented Mar 21, 2024

I @Alexey-Ayupov. According to my research, the error UND_ERR_CONNECT_TIMEOUT related to DNS, and community reports mostly about IPv6, that's why I brought up IPv6. I cannot relate this to any outbound request limitation, even second/third requests fails after 10 seconds interval.

The test failing is simple:

const urls = [
    'https://web.archive.org/web/20221029145712/https://kb.mozillazine.org/Downloads.rdf',
    'https://web.archive.org/web/20240120213614/https://techcommunity.microsoft.com/t5/windows-it-pro-blog/group-configuration-search-highlights-in-windows/ba-p/3263989',
    'https://web.archive.org/web/20230929132845/https://support.microsoft.com/en-us/topic/compatibility-update-for-keeping-windows-up-to-date-in-windows-server-2012-r2-and-windows-server-2008-r2-sp1-c62197fb-d711-f7d3-f135-172844b9f322',
    'https://web.archive.org/web/20231004100105/https://nvd.nist.gov/vuln/search/results?form_type=Basic&results_type=overview&query=microsoft+store&queryType=phrase&search_type=all&isCpeNameSearch=false',
    'https://web.archive.org/web/20240219205516/https://wiki.archlinux.org/title/spotify',
    'https://web.archive.org/web/20240119160347/https://github.com/undergroundwires/privacy.sexy/issues/247',
    'https://web.archive.org/web/20231206171559/https://bestgamingtips.com/fix-xbox-identity-provider-not-working/',
    'https://web.archive.org/web/20230806192800/https://www.hexacorn.com/blog/2018/09/02/beyond-good-ol-run-key-part-86/',
    'https://web.archive.org/web/20231020012236/https://answers.microsoft.com/es-es/windows/forum/all/windows-10-carpeta-y-archivos-sih/4d318121-fed6-4202-8b92-d4dc236b468e',
    'https://web.archive.org/web/20221029141626/https://kb.mozillazine.org/Places.sqlite'
  ];
  for (const url of urls) {
    console.log('Fetching: ', url);
    const response = await fetch(url, { method: 'HEAD'});
    await sleep(10000);
    expect(response.status).to.equal(200);
  }

The error I'm getting after first, sometimes second request:

Caused by: ConnectTimeoutError: Connect Timeout Error

@mikhailkoliada
Copy link
Contributor

hosted runners do not support ipv6 yet, that is why every "real" ipv6 inquiry will fail, and there is no ETA on ipv6 fully available unfortunately.

@undergroundwires
Copy link
Author

Hi @mikhailkoliada, I tested more and verify that this is not about IPv6 requests being made.

This is how I prove it's not about IPv6 resolution directly:

  • It happens also when I set dns.setDefaultResultOrder('ipv4first'); which forces IPv4 resolution. I added that test to tests in the repository.
    Configuration: vite-test.spec.ts
  • I tell ubuntu to prefer IPv4 through: sudo sh -c "echo 'precedence ::ffff:0:0/96 100' >> /etc/gai.conf"
    Configuration: .github/workflows/test.yaml
  • I disable IPv6 on host container completely:
      sysctl -w net.ipv6.conf.all.disable_ipv6=1
      sysctl -w net.ipv6.conf.default.disable_ipv6=1
      sysctl -w net.ipv6.conf.lo.disable_ipv6=1
    
    
    Configuration: .github/workflows/test.yaml

I get UND_ERR_CONNECT_TIMEOUT regardless.

Can it be possible that this is because of some ongoing connection (network/DNS requests) limitation in the image or cloud service you're running?

undergroundwires added a commit to undergroundwires/privacy.sexy that referenced this issue Mar 29, 2024
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
@undergroundwires
Copy link
Author

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:

  1. Create a script called force-ipv4.sh, that configures system to prefer IPv4 over IPv6, call it to configure the machine. It was not easy to find a reliable cross-platform solution and I went Cloudflare WARP for DNS resolution along with some system configurations.
  2. To easily use the script in GitHub workflows, create GitHub action called force-ipv4 and call it in GitHub runners.
  3. Fixes the IPv6 request issues, and you can happily run e.g. fetch API from Node.

Related commit introducing this fix: undergroundwires/privacy.sexy@52fadcd

undergroundwires added a commit to undergroundwires/privacy.sexy that referenced this issue Mar 30, 2024
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
undergroundwires added a commit to undergroundwires/privacy.sexy that referenced this issue Mar 30, 2024
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants