#762·camoufox

Content process OOMs to ~15 GB on ad-heavy page with uBlock Origin excluded

Author: Andruxa0125Created Sep 7, 2026Updated Sep 7, 2026
Labelsbug

Describe the bug:

With the bundled uBlock Origin excluded, loading an ad-heavy page causes the Firefox content process to grow to ~15 GB and crash. Playwright then reports Target crashed on the next call. The parent process is unaffected, so this is not an IPC or protocol problem.

Measured live during a crash (ps -eo rss):

content process:   15,393 MB      <- the tab
parent process:       479 MB      <- flat throughout, before and after

The browser's own stderr (via DEBUG=pw:browser) shows the allocator finally giving up:

[pid=45][err] out of memory: 0x00000000000000A0 bytes requested
!!! PAGE CRASH EVENT

A 160-byte allocation failing on a host with 51 GB free is the tail end of the runaway, not the cause.

What I verified:

  • Happens on v152.0.4-beta.28 and v152.0.4-beta.30 (latest) — roughly 4 of every 5 runs.
  • Does not happen on the previous stack: camoufox==0.4.11 / playwright==1.50.0 / browser v135.0.1-beta.24 — 3/3 clean on the identical script and page, with uBlock Origin excluded exactly the same way. That is the last configuration I know to be good.
  • Does not happen when uBlock Origin is left enabled — 3/3 clean, page loads instantly.
  • Not environment-related: reproduces outside Docker, on the host, with a default camoufox fetch install, no proxy, and the snippet below as the entire script. Also ruled out cgroup limits (none), host memory (51 GB free) and /dev/shm (still crashes at --shm-size=2g).
  • No interaction required. Load the page and make no further calls at all — the tab still crashes. It is not triggered by anything the automation does; any later call merely surfaces it. The delay before Target crashed is the process climbing to 15 GB, not a hang.
  • beta.28 and beta.30 share the same SourceStamp (e39c605adc0fc049a165d7fe4a3f6517b761edf7), which is presumably why the newer build doesn't help.

The page pulls a fairly typical adult-site ad stack — acscdn.com/script/aclib.js, creative.xlviiirdr.com/... (compiles asm.js), camhours.com widgets, hotjar. Nothing exotic.

Caveats, in the interest of not overstating:

  • A stock Firefox 154 on the same machine renders the page without trouble. I did not audit that profile's extensions, so I can't rule out that it has its own ad blocking — treat that comparison as suggestive rather than controlled.
  • The site rotates ad creatives continuously, so I cannot guarantee the old and new stacks were served byte-identical payloads. The 3/3 vs 4/5 split is consistent across a couple of hours, but treat it as strong rather than airtight.
  • The test URL is a NSFW adult site. It's the case I have that reproduces reliably; I'd expect any sufficiently ad-saturated page to do the same, but I haven't found a SFW equivalent.

Screenshots:

N/A — the failure is a frozen then dead tab; the memory figures above are the useful artifact.

To Reproduce:

python
import time
from camoufox.sync_api import Camoufox
from camoufox import DefaultAddons

# exclude_addons is the only non-default argument. With uBlock Origin enabled this never reproduces.
with Camoufox(exclude_addons=[DefaultAddons.UBO]) as browser:
    page = browser.new_context().new_page()
    page.on("crash", lambda _: print("!!! CRASH"))

    page.goto("https://camstreams.tv/", timeout=60000)   # NSFW
    time.sleep(150)   # make no further calls - the tab dies on its own

That is the whole reproduction: open the page and wait. No interaction with the page is needed. (time.sleep blocks sync Playwright's event dispatch, so the crash callback only prints once the sleep returns — the crash itself happens during the wait.)

Any call made after the crash raises, if you would rather see it as an exception:

python
    page.evaluate("() => 1+1")   # Error: Page.evaluate: Target crashed

Run with DEBUG=pw:browser to see the out of memory line from the browser itself, and watch ps -eo rss,args | grep camoufox during the pause to see the content process climb.

Stack trace:

From the real application rather than the snippet (our own frames renamed). The call that surfaces it is incidental. Any call made after the crash raises the same way.

Traceback (most recent call last):
  File "/app/worker.py", line 40, in handle_task
    scraper.start()
  File "/app/scraper.py", line 150, in start
    self.perform_action(self.handle_website_entry)
  File "/app/browser_base.py", line 464, in handle_website_entry
    buttons = self.page.query_selector_all('button, input[type="button"], div[role="button"]')
  File "/usr/local/lib/python3.10/dist-packages/playwright/sync_api/_generated.py", line 8857, in query_selector_all
    self._sync(self._impl_obj.query_selector_all(selector=selector))
  File "/usr/local/lib/python3.10/dist-packages/playwright/_impl/_sync_base.py", line 115, in _sync
    return task.result()
  File "/usr/local/lib/python3.10/dist-packages/playwright/_impl/_page.py", line 418, in query_selector_all
    return await self._main_frame.query_selector_all(selector)
  File "/usr/local/lib/python3.10/dist-packages/playwright/_impl/_frame.py", line 380, in query_selector_all
    await self._channel.send(
  File "/usr/local/lib/python3.10/dist-packages/playwright/_impl/_connection.py", line 69, in send
    return await self._connection.wrap_api_call(
  File "/usr/local/lib/python3.10/dist-packages/playwright/_impl/_connection.py", line 563, in wrap_api_call
    raise rewrite_error(error, f"{parsed_st['apiName']}: {error}") from None
playwright._impl._errors.Error: Page.query_selector_all: Target crashed

On 0.5.4 / Playwright 1.60.0 the same failure surfaced as the vaguer playwright._impl._errors.TargetClosedError: Target page, context or browser has been closed. Playwright 1.61.0 reports it correctly as Target crashed.

Version:

Python Packages
  Camoufox                    v0.5.6
  Browserforge                v1.2.4
  Apify Fingerprints          v0.15.0
  Playwright                  v1.61.0
Browser
  Active                      official/stable
  Current browser             v152.0.4-beta.30
  Build date                  Sep 1
  SHA256                      5720d45b894c

Host: Ubuntu 22.04.5 LTS, kernel 6.8.0-60-generic, Python 3.10.12, 62 GB RAM.