cypress: XHR requests are cancelled and re-issued if they don't return in 30 seconds
Current behavior:
When an XHR request takes more than 30 seconds to complete, Cypress cancels the request and issues it again. Depending on what the server does with those requests, this can cause all sorts of problems (e.g. creating duplicate things, or directly resulting in failed tests when the server replies with a 5xx error that it wouldn’t have issued if the request hadn’t been sent twice).
Desired behavior:
Cypress should never retry an XHR request on its own, because it cannot know what the effects of a duplicate request could be.
Test code to reproduce
cypress-bug.zip (also contains the video generated by Cypress for the failing test).
I used the code in that zip file to generate the screen recording below. The idea is to set up a web server with an API call that takes 34 seconds to reply, then run a Cypress test that visits the home of the web server (which just issues an XHR call to the API method) and waits for the API response, with a timeout longer than the time it takes for the API to respond. You’ll see on the logs of the webserver that the API method gets called twice, the second one pretty much exactly 30 seconds after the first one.
To work with the code:
- run
npm ion both thewebserverandtesterfolders - run
node index.jsfrom thewebserverfolder - once it’s running,
npm run cypressfrom thetesterfolder
You’ll see that the webserver logs one call to /, one to /api, and ~30 seconds later another call to /api. Cypress then reports a failed test.
Versions
The issue happens starting with Cypress 3.8.0 (tested with 3.6.1, 3.7.0, 3.8.0, 4.0.1) Windows 10 Headless tests with Electron
Additional information
I originally discovered this with the Cypress Docker images. In the project where I found it I could even see Nginx reporting that the client (Cypress running tests) had closed the connection, right before receiving the duplicate request.
Screen recording of the code above showing the issue.

About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 4
- Comments: 23 (10 by maintainers)
@jennifer-shehane I think the part right before where you started the quote is also very relevant (emphasis mine):
In this case the client is already “directly connected to an HTTP/1.1 origin server”, right? It sent the request and is only waiting for the server to reply. I can see why if the client has not yet established a connection to the origin server, and it sees a connection close, then it should retry the request, because it’s guaranteed that the server has not received it before. But once it established a connection with the server, I’d imagine that it should not retry a request that it already sent, no matter the kind of failure it sees (including a closed connection), otherwise the spec would be calling for potentially issuing POST requests to the server several times, which I’m not sure makes sense…
Besides that, note that the timeout I specified for Cypress in the repro was 35 seconds, so Cypress should not be aborting these requests at the 30 second mark, correct?
Have experienced this behavior as well on version 4.4.0 (likely older versions as well but was not caught until recent update) at both timeouts of 60 seconds and 25 seconds (after seeing this open issue). Requests are made exactly 60 or 25 seconds apart, respectively, after the timeout occurs when the test with the related XHR request fails.