How to fix net::ERR_INTERNET_DISCONNECTED or net::ERR_FAILED in Playwright?

Playwright

net::ERR_INTERNET_DISCONNECTED means the browser has no active network path to reach the target — either the machine itself is offline, the CI environment has outbound network disabled, or a Playwright page.route() handler or context offline setting is blocking the request. net::ERR_FAILED is a broader catch-all that covers firewall drops, proxy failures, and TLS errors that don't fall into a more specific category. Both appear as thrown exceptions from page.goto() or from resource loads during page rendering.

Common mistake

test('loads user profile from API', async ({ page }) => {
  await page.goto('https://app.example.com/profile');

  // Test relies on live API that is unreachable in offline CI
  await expect(page.getByText('Ada Lovelace')).toBeVisible();
});

Tests that depend on external APIs or CDN resources will produce ERR_INTERNET_DISCONNECTED on CI environments where outbound access is restricted, or intermittently when those services have downtime.

The fix

Mock external dependencies with page.route() to make tests network-independent:

import { test, expect } from '@playwright/test';

test('displays user profile', async ({ page }) => {
  await page.route('**/api/v1/profile', (route) =>
    route.fulfill({
      status: 200,
      contentType: 'application/json',
      body: JSON.stringify({ id: 42, name: 'Ada Lovelace', plan: 'pro' }),
    })
  );

  await page.goto('https://app.example.com/profile');
  await expect(page.getByRole('heading', { name: 'Ada Lovelace' })).toBeVisible();
});

For offline behavior testing — Playwright can simulate a network-offline context:

test('shows offline banner when disconnected', async ({ page, context }) => {
  await page.goto('https://app.example.com');

  // Simulate offline
  await context.setOffline(true);
  await page.getByRole('button', { name: 'Refresh feed' }).click();

  await expect(page.getByRole('alert', { name: /offline/i })).toBeVisible();
});

For CI with restricted outbound network — identify which hosts are needed and either mock them or allowlist them in the CI network policy.

Why it works

page.route() intercepts requests at the browser level before they reach the network, so the test never needs a live connection for mocked endpoints. The handler runs synchronously in the Node.js process, making the test fully deterministic regardless of external service availability. context.setOffline(true) uses the Chrome DevTools Protocol to flip the network adapter off, which lets you test offline UI states without actually disconnecting the machine.

Tips

  • Separate network-dependent integration tests into a dedicated CI job that runs against a real staging environment, and keep the main test suite fully mocked and network-independent.
  • Use page.on('requestfailed', req => console.log(req.url(), req.failure())) during debugging to identify exactly which requests are failing and with what error code.
  • For ERR_FAILED errors that only happen on specific resource types (fonts, CDN scripts), use page.route() with a wildcard pattern to stub or abort those non-critical assets.
  • If the error is playwright offline net::ERR_INTERNET_DISCONNECTED and you didn't intend to go offline, check whether a previous test left context.setOffline(true) active — fixture isolation prevents this when using Playwright Test's built-in fixtures.