skip to content

Your Cypress 16 suite passes only with `forceHttp1: true`. Is that an acceptable place to stop?

level: principalimportance: nice to knowfreq 30%

answer

  1. Deprecated in the release that added it
  2. Buys time, not a solution
  3. Project-wide, never per test
  4. Name the difference you depend on
  5. Exit criterion is the flag removed

basics

~20 s

Only as a dated migration step. Cypress introduced and deprecated forceHttp1 in the same release, so leaving it on trades a green suite for a run that no longer tests the protocol, the certificate or the cache your users get.

solid answer

~50 s

`forceHttp1: true` routes **every** browser through the legacy network path and restores the Cypress 15 behaviour. It is a legitimate short-term move: it unblocks a release while you work through a list of assertion changes, and it is the right lever if you hit undocumented behaviour on the native browser network. What makes it debt is that Cypress **introduced and deprecated it in the same release** — it exists to buy migration time and will be removed once the native path is supported long term. Leaving it on means your suite keeps testing an HTTP/1.1 downgrade, a Cypress-issued certificate and a cache Cypress sits in front of, none of which your users experience. So set it with a date and an owner, identify **which** documented difference your suite depends on, file an issue if it is not one of them, and fix the assertions rather than the switch.

go deeper

for a junior

Know that forceHttp1 exists, that it puts every browser back on the legacy network path, and that Cypress marked it deprecated in the same release that added it.

for a middle

Be ready to explain what turning it on restores and what it costs, and that it is project-wide, cannot be set per test, and restarts the Cypress server.

for a senior

Show that you would identify the specific documented difference forcing the flag, migrate the assertions, and file an issue if the behaviour is not on the documented list.

for a principal

Own the standard behind it: whether the suite may assert on transport at all, who owns a deprecated compatibility flag, and what the exit criterion and date are.

## What the switch actually buys and costs `forceHttp1: true` is a project-level configuration option that routes every browser through the **legacy network path** — the pre-16 arrangement in which Cypress holds the connection between the browser and your server. Setting it restores the old `cy.intercept()` behaviour wholesale: `req.httpVersion` reports `'1.1'` again, compression headers reappear on intercepted responses, revalidations show `304`, and Cypress terminates TLS for the application under test. Changing it restarts the Cypress server, and it **cannot be set per test or per suite** — it is all-or-nothing for the project. The cost is that the suite goes back to testing something your users never do: - **The protocol is wrong.** Requests are downgraded to HTTP/1.1 and queue behind the per-origin connection ceiling, so a request-heavy dashboard behaves differently under test than in production, and HTTP/2 or HTTP/3 specific behaviour is unreachable. - **The certificate is wrong.** Cypress acts as its own certificate authority and issues a certificate for the origin under test, instead of the browser validating your real one. - **The network panel is wrong.** Request modifications are applied after the browser has logged the request, so what you changed is not what the browser records. ## Why "it is deprecated already" is the decisive fact Cypress **introduced and deprecated `forceHttp1` in the same release**. That is an unusually clear signal: the option exists to give suites time to migrate, or as a temporary escape hatch while an issue you filed is investigated, and it will be removed once the native browser network is supported long term. Setting it prints a warning on every run. Reading that correctly is the judgement being tested. An option that is deprecated at birth is not a supported configuration choice with a trade-off to weigh — it is **a countdown**. Any plan that treats it as a setting rather than as a scheduled piece of work is planning for a forced migration later, under whatever deadline the removal lands on. ## The decision I would defend 1. **Turn it on to unblock, not to finish.** A red suite blocking a release is a real cost; take the switch, and record the date you took it. 2. **Identify which difference you actually depend on.** The behaviour changes are documented and short: transport metadata, compression headers, request `content-length`, revalidations reported as `200`, stubbed responses never cached, responses the browser rejects, and `responseTimeout` no longer bounding a response handler. Find yours before you write a plan. 3. **File an issue if it is not on that list.** If the switch fixes something undocumented, that is a bug report, and filing it is what keeps the escape hatch honest for everyone. 4. **Fix the assertions, not the transport.** Most of the work is replacing transport assertions with application ones; the residue is a handful of assertions gated by `Cypress.isBrowser()` for the browsers still on the legacy path. 5. **Delete the option and keep the run green.** The exit criterion is the flag removed, not the suite passing with it on. | Position | Defensible when | Fails when | |---|---|---| | On, with a date and an owner | Migrating, or an issue is open | The date passes unremarked | | On, indefinitely | Never in a maintained suite | Removal lands on a deadline | | Off, with gated assertions | The differences are understood | Nobody owns the gates | ## What makes this an organisational call, not a technical one The technical fix is small and mostly mechanical. What is hard is the standard the team adopts: **whether a test suite is allowed to assert on transport at all.** Every assertion this migration breaks was an assertion about the plumbing rather than about the product, and a team that writes those will collect the same debt at the next runner change, the next proxy change, the next protocol change. The durable position is to say so out loud — tests assert on what the application did, transport assertions need a written reason — and to treat a compatibility switch as a tracked item with a name against it. The alternative, a flag nobody owns quietly diverging the test environment from production, is how a suite stops being evidence. ## What to remember - `forceHttp1` is a **migration aid deprecated at introduction**, project-wide, and it restarts the Cypress server when changed. - Leaving it on keeps testing HTTP/1.1, a Cypress-issued certificate, and a cache Cypress sits in front of. - The exit criterion is the flag removed, not the suite green with it on. - If the difference that forces it is undocumented, filing the issue is part of the job.

  • Can you scope forceHttp1 to only the specs that need it?
    No. It is a project-level option that cannot be set per test or per suite, and changing it restarts the Cypress server. That is part of why it is a poor long-term answer: one spec's dependency drags the whole run onto the legacy network path.
  • What would you put in place so the flag is actually removed rather than forgotten?
    A tracked item with a named owner and a date, the list of assertions that depend on the legacy path attached to it, and a review that treats a still-set deprecated flag as a failing condition. The per-run deprecation warning helps, but a warning nobody reads is not a control.

saying these in an interview costs you the question

  • Calls forceHttp1 a supported long-term configuration
  • Sets it project-wide and closes the ticket
  • Believes it can be scoped to one spec
  • Never checks which documented difference forced it
  • Reports the suite green without naming the trade