October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsSlow PC?RecommendedPC slow today? Run a repair scan before it gets worseResolve common Windows issues and optimize system performance.Scan NowOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
Chrome

How to Fix Chrome Extension Background Page Load Errors in Headless Selenium

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A Chrome extension that fails to load in headless Selenium is most often started with the wrong headless mode, an invalid unpacked-extension path, incompatible Chrome and ChromeDriver versions, or a Manifest V3 background worker being treated like a persistent page. Start by capturing the complete error, exact browser and driver versions, Selenium version, manifest version, extension path, and every Chrome launch argument. Then work through the checks below in order; a message mentioning a “background page” does not identify one universal fault.

1. Start Chrome with the extension-compatible headless mode

Chrome’s official extension end-to-end testing guide says to launch tests with --headless=new; the older headless implementation does not support loading extensions. Add the flag through Selenium’s Chrome options and verify that a CI wrapper, container entrypoint, or shared capability is not replacing it. See Chrome’s extension testing guidance.

Python example

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.add_argument("--headless=new")
options.add_argument("--load-extension=/absolute/path/to/unpacked-extension")
options.add_argument("--no-sandbox")
options.add_argument("--disable-dev-shm-usage")

driver = webdriver.Chrome(options=options)
try:
    driver.get("https://example.com")
    print(driver.title)
finally:
    driver.quit()

--no-sandbox and --disable-dev-shm-usage can be necessary in restricted Linux containers, but they do not fix an invalid extension. Use only the arguments your environment requires.

Compare with a headed diagnostic run

Run the same test without a headless flag, or under a virtual display, as a control when investigating an environment-specific failure. If headed and new-headless runs differ, record that observation; it does not by itself prove that headless mode is the root cause. The documented extension-testing fix is selecting --headless=new, not assuming that every headed/headless difference has the same explanation.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

2. Load an unpacked extension from its real root

Selenium exposes Chrome arguments through its options API, and its Chrome documentation uses load-extension for unpacked extensions. The value must be an absolute directory containing the extension’s manifest.json, not a ZIP file and not a parent directory that merely contains the unpacked folder. Selenium’s instructions are at Chrome specific functionality.

  1. Unzip or build the extension into a stable directory available inside the test environment.
  2. Confirm that /absolute/path/to/unpacked-extension/manifest.json exists and is readable by the user running Chrome.
  3. Pass that directory exactly once with --load-extension=....
  4. Print the resolved path and the complete Chrome arguments in CI logs (excluding secrets).
  5. Ensure the test is not selecting a different profile or launching a second browser without the extension argument.

A relative path that works on a workstation can point somewhere else in a container. Resolve it before creating the driver:

from pathlib import Path
extension_dir = Path("./dist/extension").resolve()
manifest = extension_dir / "manifest.json"
if not manifest.is_file():
    raise FileNotFoundError(f"No manifest at {manifest}")
options.add_argument(f"--load-extension={extension_dir}")

3. Verify Chrome, ChromeDriver and Selenium versions

Selenium states that ChromeDriver and the Chrome browser should match and that a mismatch causes a driver error. Record the exact versions rather than labels such as “latest”; this catches browser-startup incompatibility, although it does not prove that an extension-specific error is caused by the mismatch.

Collect the versions

  • Chrome: run google-chrome --version, chromium --version, or the equivalent command for your image.
  • ChromeDriver: run chromedriver --version or inspect the driver binary selected by Selenium Manager.
  • Selenium: run python -c "import selenium; print(selenium.__version__)" or inspect your language package lockfile.
  • CI image and operating-system details: record the image tag, architecture and whether a display server is present.

Upgrade or pin the browser and driver as a tested pair. Do not silently mix a system Chrome with a driver downloaded for another image.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

4. Check whether the extension is Manifest V2 or Manifest V3

Open manifest.json and identify manifest_version. Manifest V2 commonly uses a background page or scripts. In Manifest V3, “background pages are replaced by a service worker,” as Chrome explains in its service-worker migration guide.

Manifest V3 declaration

{
  "manifest_version": 3,
  "name": "Example extension",
  "version": "1.0.0",
  "background": {
    "service_worker": "background.js"
  },
  "permissions": ["storage"]
}

background.service_worker is a single worker filename. The old background.scripts and background.persistent pattern is not the MV3 declaration. Check that the named file exists at the path implied by the manifest and that its syntax parses in the target Chrome version.

Worker-only behavior that looks like a load failure

An MV3 service worker has no DOM and no window. Move DOM operations to a popup, content script, or (where appropriate) an offscreen document. Register event listeners synchronously at top level so Chrome can dispatch events after startup. Replace XMLHttpRequest with fetch, persist state in extension storage instead of relying on globals, and use alarms for work that must survive worker shutdown. Chrome’s Manifest V3 migration checklist covers these changes.

Workers can stop when idle. A log line or test assertion that expects a permanently open “background page” may therefore be testing the wrong lifecycle. A worker that becomes idle is not automatically a failed extension load.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

5. Separate extension loading from test observation

Chrome’s testing guide notes that Selenium cannot access the service worker through the approach shown for Puppeteer. Instead, navigate to an extension page, such as a popup, and execute code there when your extension exposes a suitable page.

# Replace EXTENSION_ID with the ID shown by your test build.
driver.get("chrome-extension://EXTENSION_ID/popup.html")
status = driver.execute_script("return document.body.innerText")
print(status)

This requires a real extension page. If the extension has no popup, add a small diagnostic page in the test build or expose another page designed for inspection. Do not infer that a worker is absent solely because a direct worker-inspection technique is unavailable in Selenium.

Debugger attachment changes lifecycle observations

Chrome also notes that ChromeDriver attaches a debugger to service workers. That attachment can prevent workers from stopping exactly as they would during ordinary browsing, so a Selenium test may observe a different lifecycle. Treat worker persistence, idle timing, and inspection results as test-environment observations rather than proof of a loading defect.

6. Capture the evidence before changing code

When the message says “background page failed to load,” save the complete stack trace and browser log. Include:

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • the complete Selenium exception, nested cause and ChromeDriver log;
  • exact Chrome and ChromeDriver versions and Selenium version;
  • the full manifest background section and manifest version;
  • the resolved extension directory and confirmation that manifest.json is readable;
  • every Chrome argument, including flags added by CI or a container image;
  • whether the failure occurs in new headless, headed, or both modes;
  • the extension page URL used for any inspection attempt.

Without these details, assigning one cause would be speculation. A browser startup error, a manifest parse error, a worker exception, and an observation mistake can produce similarly worded reports.

7. A repeatable minimal test

Reduce the problem to one extension and one navigation. First load an extension whose manifest contains only a valid MV3 worker that logs a message. Then add permissions, APIs and application code one change at a time.

// background.js
chrome.runtime.onInstalled.addListener(() => {
  console.log("extension installed");
});
{
  "manifest_version": 3,
  "name": "Minimal test",
  "version": "1.0.0",
  "background": { "service_worker": "background.js" }
}

If this minimal build starts with --headless=new but the production build does not, compare manifests and worker code rather than changing unrelated Selenium flags. Add the production permissions and listeners incrementally, checking syntax and API availability after each change.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

8. Troubleshooting by symptom

“Extensions are not supported” or the extension is missing

Check for the old --headless mode, a wrapper that strips --headless=new, or a second Chrome launch. Print the final capabilities and arguments received by the driver.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

“Load extension failed” immediately at startup

Verify the absolute path, permissions and presence of manifest.json. Confirm that the path is inside the container, not only on the host. Validate JSON syntax and referenced files.

ChromeDriver exits before the test starts

Compare exact Chrome and ChromeDriver versions, architecture and executable paths. This is a browser-driver startup problem; do not label it an MV3 worker failure until Chrome starts successfully.

The worker starts, then appears to disappear

Check whether the extension is MV3. Idle shutdown is expected worker behavior. Persist state, register listeners at top level and use alarms for scheduled work. Account for ChromeDriver’s debugger attachment when interpreting lifecycle logs.

The popup opens but application state is empty

Inspect storage initialization, permissions and message timing. Navigate to the extension page only after the driver has started, and wait for the page’s own readiness condition instead of assuming a persistent background page is available.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Headless fails but headed mode works

Record the difference, then verify --headless=new, paths, versions and worker assumptions. Use headed execution as a diagnostic control, not as evidence that a particular workaround is universally required.

Or skip the browser setup

If your goal is obtaining a clean screenshot rather than testing extension behavior, ScreenshotNeo provides a website screenshot API and MCP server. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups and chat widgets; each step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and responses identify the page verdict and billing status in X-Page-Verdict and X-Billed headers.

One request is enough:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

See the ScreenshotNeo documentation for options such as full-page capture, CSS selectors, device presets, dark mode, PDFs, custom JavaScript, waits, cookies, headers, geolocation, caching and asynchronous jobs. Its MCP server exposes take_screenshot, get_page_info and capture_pdf to Claude, Cursor and other MCP clients. The Free plan includes 1,000 shots each month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.

Frequently asked questions

Does every “background page” error mean the extension did not load?

No. MV3 uses a service worker, and a worker that is idle or difficult to inspect through Selenium is not necessarily a load failure.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Can I keep using Manifest V2 code in an MV3 extension?

No. MV3 requires the service-worker model and its constraints; update the manifest and worker code together.

Should I switch permanently to headed Chrome?

Not as a general fix. Use headed execution as a comparison run while correcting the documented new-headless configuration and other evidence-based causes.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Read next

Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.