Skip to content

[Regression]: http:// navigations are upgraded to https:// in Chromium 158, Chrome and Edge #43871

Closed

Description

Last Good Version

1.64.1

First Bad Version

1.65.0-next. Two changes cause this:

Steps to reproduce

Neither script needs an external site.

A host that has only http:

const http = require('http');
const { chromium } = require('playwright');

(async () => {
  const server = http.createServer((req, res) => res.end('served over http'));
  await new Promise(resolve => server.listen(0, '127.0.0.1', resolve));
  const { port } = server.address();

  const browser = await chromium.launch({
    channel: 'chromium',
    args: [`--host-resolver-rules=MAP staging.example.org:80 127.0.0.1:${port},MAP staging.example.org:443 127.0.0.1:9`],
  });
  const page = await browser.newPage();
  await page.goto('http://staging.example.org/');
  console.log(page.url());
  await browser.close();
  server.close();
})();

A mock of an http:// URL:

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch({ channel: 'chrome' });
  const page = await browser.newPage();
  await page.route('http://app.example.org/', route => route.fulfill({ contentType: 'text/html', body: 'mocked' }));
  await page.goto('http://app.example.org/');
  console.log(await page.textContent('body'));
  await browser.close();
})();

Expected behavior

Playwright has disabled HTTPS upgrades since 2023 (#27605), so users expect the following:

  • page.goto('http://...') opens that URL, and page.url() and toHaveURL() report it.
  • page.route() for an http:// URL receives the request. The mocked host does not have to exist.
  • One navigation makes one navigation request. page.on('request'), HAR files and proxy logs show only that request.
  • A test gives the same result headless and headed. A developer can run --headed or --debug to investigate a failure from CI.

Actual behavior

The first script fails with page.goto: net::ERR_BLOCKED_BY_CLIENT at http://staging.example.org/. The error does not say that an HTTPS upgrade is the cause.

The second script fails with page.goto: net::ERR_NAME_NOT_RESOLVED at http://app.example.org/, because the request goes to https:// and the route does not match.

Scenario 1.64.1, Chrome 156 main, headless shell 158 main, Chromium 158 headed or chromium channel main, Chrome 156 or Edge 155
http:// host with no HTTPS Opens, 1 request Opens, 1 request net::ERR_BLOCKED_BY_CLIENT Opens, 3 requests
page.route() mock of an http:// URL Mocked Mocked net::ERR_NAME_NOT_RESOLVED net::ERR_NAME_NOT_RESOLVED
HTTP proxy that rejects CONNECT Opens, 1 request Opens, 1 request net::ERR_BLOCKED_BY_CLIENT Opens, 3 requests
Public host with HTTP and HTTPS Stays on http:// Stays on http:// Moves to https:// Moves to https://
http://localhost:<port> No change No change No change No change

Requests are navigation requests seen by page.on('request'). Tested on Linux with 8195aab, Chromium 158.0.8127.2, Chrome 156.0.8078.47 and Edge 155.0.4283.62.

Who is affected

  • Headed runs and new headless: --headed, --debug and channel: 'chromium'. The default headless shell does not have this feature, so a test can pass on CI and fail when a developer runs it headed.
  • Chrome and Edge: channel: 'chrome' and channel: 'msedge'. This includes Playwright MCP, which uses the chrome channel by default.
  • Common setups: staging hosts on port 80 with a public-looking name, tests that mock http:// URLs, and HTTP proxies.

Our test suite did not detect this, because localhost, private IP addresses and non-default ports are never upgraded. #43454 changed the proxy tests to use an exempt host name. Users would have to make the same change to their tests.

This does not affect only 1.65

Disabling HttpsUpgrades alone has no effect on Chromium 158. Playwright 1.64.1 with the Chromium 158 build (r1253) gives net::ERR_BLOCKED_BY_CLIENT in the same scenarios.

Chrome 158 is scheduled for early stable on 2026-11-04 and stable on 2026-11-17. I expect channel: 'chrome' and Playwright MCP to fail on these dates with every current Playwright version. I tested with the Chromium 158 build, because Chrome 158 stable is not available yet.

Users cannot safely work around this

The workaround from #43455 is args: ['--disable-features=HttpsUpgrades,HttpsFirstBalancedModeAutoEnable']. Chromium uses only the last --disable-features flag, so this replaces the list that Playwright passes, including ThirdPartyStoragePartitioning and PaintHolding. I confirmed this by passing the flag twice: only the last one had an effect. A safe workaround must repeat the full Playwright list, which changes between versions.

Recommendation for 1.65

Option http:// host with no HTTPS Route mock Proxy without CONNECT URL stays on http://
Ship main without a change Fails on Chromium 158 Fails Fails on Chromium 158 No
Disable only HttpsFirstBalancedModeAutoEnable Opens, 3 requests Fails Opens, 3 requests No
Disable both features Opens, 1 request Mocked Opens, 1 request Yes

Disabling both features gave the 1.64.1 result in every scenario above, on headed Chromium 158, the chromium channel, Chrome 156 and Edge 155. I tested this by passing the full default list plus the two features.

Recommended steps:

  1. Before we cut release-1.65, add HttpsUpgrades and HttpsFirstBalancedModeAutoEnable to disabledFeatures in packages/playwright-core/src/server/chromium/chromiumSwitches.ts. This reverts chore(chromium): stop disabling the HttpsUpgrades feature #43455.
  2. Add a regression test that navigates to a public-looking host name through --host-resolver-rules, because localhost is exempt. Run it on headed Chromium, the chromium channel and the chrome channel. Chromium can remove or rename these features, and this test will then fail on the next roll.
  3. Remove the HTTPS upgrade item from the 1.65 breaking changes.
  4. Release 1.65 before Chrome 158 stable on 2026-11-17, and consider a 1.64 patch release with the same change.
  5. If we want real browser behavior later, add it as an explicit option with its own announcement. It should not come as a side effect of a Chromium roll.

Activity

  1. github-actions commented on Nov 3, 2026

    @github-actions
  2. microsoft-playwright-automation commented on Nov 3, 2026

    @microsoft-playwright-automation
    Contributor

    Hi, I'm the Playwright bot and I reproduced this on Linux.

    Reproduced on 1.65.0-next (47ba108f675b046e9290483f253631ec0c11384b). Chromium 158 blocks the HTTP navigation; Chrome 156 and Edge 156 make three navigation requests instead of one. The default headless shell is unaffected. Disabling both HttpsUpgrades and HttpsFirstBalancedModeAutoEnable restores HTTP navigation and HTTP route mocks.

    The proposal extends the existing proxy test with a public-looking hostname and checks the final URL and navigation request count.

    Verification
    Browser on Linux Without the fix: HTTP proxy navigation With the fix
    Chromium 158.0.8127.2, chromium channel net::ERR_BLOCKED_BY_CLIENT Pass, one HTTP request
    Chromium 158.0.8127.2, default headless shell Pass Pass, one HTTP request
    Chrome 156.0.8078.47 HTTP → HTTPS → HTTP Pass, one HTTP request
    Edge 156.0.4314.42 HTTP → HTTPS → HTTP Pass, one HTTP request
    Firefox 159.0 Not tested Pass
    WebKit 27.2 Not tested Pass

    Headed Chromium also passes with the fix. Separate fixture-based checks confirmed that port-80 HTTP navigation through --host-resolver-rules and an exact http:// route mock both pass with the fix on headed Chromium, the chromium channel, Chrome and Edge.

    The proxy and browser-context proxy suites passed on all three engines: 152 passed, 4 skipped. npm run build and npm run flint passed.

    Draft PR: #43877

    Triaged on Linux by the Playwright bot - agent run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions