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

IPv6 used for cypress backendUrl connection check #27962

Closed
mduft opened this issue Oct 3, 2023 · 14 comments
Closed

IPv6 used for cypress backendUrl connection check #27962

mduft opened this issue Oct 3, 2023 · 14 comments

Comments

@mduft
Copy link

mduft commented Oct 3, 2023

Current behavior

Cypress seems to use IPv6 to perform the connections check, which makes it fail in my setup.

We're launching the backend (angular) using ng serve --host 0.0.0.0 , then asserting that the backend indeed is reachable. The run cypress. It will issue the connection check warning in case of headed, and additionally fail in case of headless. In headed mode if I ignore the warning and start a test, everything works perfectly.

I tried many things to fix the issue, and discovered that removing the ::1 mapping from /etc/hosts will make things work again. However this is not a fix, but merely a workaround.

Desired behavior

The connection check should correctly detect my server is running.

Test code to reproduce

have a machine where localhost resolves to ::1. Run a backend (e.g. angular) using --host 0.0.0.0, which seems to bind to IPv4 only. Run cypress.

Cypress Version

13.3.0

Node version

v18.17.0

Operating System

Fedora release 38 (Thirty Eight) - 6.5.5-200.fc38.x86_64

Debug Logs

With `::1` in /etc/hosts (default Linux setup):

2023-10-03T09:23:55.034Z cypress:network:agent addRequest called { isHttps: false, href: 'http://localhost:4210/' }
2023-10-03T09:23:55.034Z cypress:network:agent got family { family: undefined, href: 'http://localhost:4210/' }
2023-10-03T09:23:55.038Z cypress:server:server-base ensuring baseUrl (http://localhost:4210) errored: r [RequestError]: Error: connect ECONNREFUSED ::1:4210 at new r (<embedded>:1868:354808) at ee.callback (<embedded>:1868:360809) at e.callback.s.callback [as _callback] (<embedded>:1868:360255) at s._callback.s.callback.s.callback (<embedded>:2086:91633) at ee.emit (node:events:513:28) at ee.onRequestError (<embedded>:2086:100575) at ClientRequest.emit (node:events:513:28) at Socket.socketErrorListener (node:_http_client:502:9) at Socket.emit (node:events:513:28) at emitErrorNT (node:internal/streams/destroy:151:8) at emitErrorCloseNT (node:internal/streams/destroy:116:3) at process.processTicksAndRejections (node:internal/process/task_queues:82:21) { cause: Error: connect ECONNREFUSED ::1:4210 at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1494:16) { errno: -111, code: 'ECONNREFUSED', syscall: 'connect', address: '::1', port: 4210 }, error: Error: connect ECONNREFUSED ::1:4210 at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1494:16) { errno: -111, code: 'ECONNREFUSED', syscall: 'connect', address: '::1', port: 4210 }, options: { url: 'http://localhost:4210', agent: F { familyCache: {}, httpAgent: [O], httpsAgent: [R] }, proxy: null, callback: [Function (anonymous)], transform: undefined, simple: true, resolveWithFullResponse: false, transform2xxOnly: false }, response: undefined }

Without `::1` in /etc/hosts:

2023-10-03T09:27:12.782Z cypress:network:agent addRequest called { isHttps: false, href: 'http://localhost:4210/' }
2023-10-03T09:27:12.782Z cypress:network:agent got family { family: undefined, href: 'http://localhost:4210/' }

... the `ensuring` log does not appear, the warning is not shown.

Other

No response

@MikeMcC399
Copy link
Contributor

MikeMcC399 commented Oct 3, 2023

@mduft

There were a lot of similar issues caused by Node.js in the migration from Node.js 16 to 18.

I put some workarounds for this on https://github.com/cypress-io/github-action#wait-on-with-nodejs-18 GitHub Actions. Although this is not what you're using, it may be helpful.

I don't have your environment, but apart from the above, there are two other things you could try:

  • Start with ng serve --host without the 0.0.0.0
  • Update to Node.js 20

In similar situations this has been helpful.
Edit: This does not work for Angular 16

The root cause is that some dev servers don't respond on both IPv4 and IPv6 stacks as they should do. It's not a Cypress bug.

@mduft
Copy link
Author

mduft commented Oct 3, 2023

Well - if I do have a server which supports only one stack, I think it is inconsistent behaviour that cypress will fail the connection check but run all the test happily. Either all fails, or all works. But a mix is not good IMHO. But thanks for the material to read :)

@MikeMcC399
Copy link
Contributor

@mduft

Which version of Angular are you using? I'd like to cross-check as I have a couple of test suites set up for related issues.

@mduft
Copy link
Author

mduft commented Oct 3, 2023

@MikeMcC399 in that case latest 16.2.4 - I noticed the issue when testing the update. Interestingly it worked a few weeks ago, however I suspect an OS update, or a change in resolution behavior etc. way more than a change in Angular itself. Node.js version was and has been since it was last working always unchanged...

@MikeMcC399
Copy link
Contributor

@mduft

According to https://angular.io/guide/versions Angular 16 is not supported on Node.js 20, so I'll have to withdraw that suggestion. 🙁

@MikeMcC399
Copy link
Contributor

MikeMcC399 commented Oct 4, 2023

@mduft

I also have to withdraw the suggestion of using ng serve --host without further parameters. This works on vite, but just causes an error on Angular 16.

I can't reproduce your issue on an out-of-the-box Fedora 38 installation running in VMware Workstation and using the same versions that you are using:

Angular 16.2.4
Node.js v18.17.0
Cypress 13.3.0
Fedora release 38 (Thirty Eight) - 6.5.5-200.fc38.x86_64

Since I can't reproduce it, it's difficult to give reliable suggestions, however here are a couple of things you could try:

export NODE_OPTIONS=--dns-result-order=ipv4first

See https://nodejs.org/dist/latest-v18.x/docs/api/all.html#all_cli_--dns-result-orderorder

Set your baseUrl to http://127.0.0.1:4210/.

Add an entry to /etc/hosts for ipv4-localhost and use that instead of referring to localhost:

127.0.0.1       ipv4-localhost

@mduft
Copy link
Author

mduft commented Oct 9, 2023

@MikeMcC399 thanks for the suggestions. I had to add the --host 0.0.0.0 for now unkown reasons a while back for cypress (10.x) to be able to connect to the backend - never really found out why. However now, with cypress 13.x I can remove --host all together and it seems to work everywhere. This has the effect that the angular server now again hosts on both v4 and v6 instead of inferring v4 from the IP format.

This is "OK" for me now, however it is still inconsistent behavior IMHO if (and I don't know if this is the case always) one part of cypress/browser uses v4 and one v6 only to connect to the backend. Not sure what triggered the problem for me though, but it was easily reproducible on my fedora ... Hmm.

@MikeMcC399
Copy link
Contributor

@mduft

It's good to see that you have a working setup now. If you say it is OK for you now, then I suggest to close this issue even though it has not been fully investigated.

Generally DNS and Node.js services translate the hostname localhost and provide one or more IP addresses, which could be IPv4, IPv6 or both, so without going quite deep into debugging it is not easy to see what ought to be changed.

@mduft
Copy link
Author

mduft commented Oct 9, 2023

Fine with me. Then it serves as documentation of the issue at least :)

@MikeMcC399
Copy link
Contributor

@mduft

Fine with me. Then it serves as documentation of the issue at least :)

In that case, would you like to click on the Close button? You should be able to see this since you are the issue Author. I can't close issues, since I'm just a community Contributor without any special privileges.

@mduft
Copy link
Author

mduft commented Oct 16, 2023

Sure thing :)

@mduft mduft closed this as completed Oct 16, 2023
@rkrisztian
Copy link

#25397 is a similar issue but still open.

@guoliang
Copy link

guoliang commented Feb 9, 2024

@mduft

export NODE_OPTIONS=--dns-result-order=ipv4first

I'm running cypress in macOS with node18, and doing the above helped my case.

@taurusx
Copy link

taurusx commented Feb 12, 2024

@MikeMcC399 gave a good clue on how to resolve it, thanks. (#27962 (comment))

...

Set your baseUrl to http://127.0.0.1:4210/.

Add an entry to /etc/hosts for ipv4-localhost and use that instead of referring to localhost:

127.0.0.1       ipv4-localhost

Our team had this ipv6 issue only present on pipelines (Docker image cypress/included run on Kubernetes). This might be specific to our cypress pipelines and config, but we decided to keep baseUrl: 'http://localhost:3000' and all of the uses of localhost in our configs. Instead, we run a script to comment out the line ::1 localhost ip6-localhost ip6-loopback in /etc/hosts for the e2e job before running cypress, and that solved the issue for us.

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

No branches or pull requests

5 participants