Skip to content

[Bug]: Docker pool's permanent browser never serves any request - signature is computed without the egress proxy, so no /crawl can ever match it #2204

Description

@SohamKukreti

Summary

Found while investigating #2202. The Docker server's "permanent" warm browser is dead weight: it is started at boot, serves zero requests, is never cleaned up, and causes every container to run a second browser tree from the first request onward.

Root cause

The pool matches requests to browsers by hashing the full BrowserConfig (crawler_pool.py:46-49), and proxy_config is part of to_dict() (async_configs.py:968).

  • init_permanent() is called at startup with a config built straight from config.ymlwithout enforce_egress() (server.py:199-203), so its fingerprint has proxy_config: None.
  • Every /crawl request's config goes through enforce_egress() first (api.py:687-690), which sets proxy_config to the egress pinning proxy — whose port is random each boot (egress_broker.py:198-201).

The two fingerprints can never be equal, so _is_default_config() (crawler_pool.py:60) never matches and PERMANENT is never returned. Note get_default_browser_config() (server.py:126-141) does apply enforce_egress, so even the server's own /html, /screenshot, /pdf, /execute_js endpoints miss it.

Additionally, the janitor only sweeps HOT_POOL and COLD_POOL (crawler_pool.py:177,198) — PERMANENT is never inspected, so the unused browser also can never be reclaimed.

Impact

Verified

Reproduced on unclecode/crawl4ai:0.9.2: fresh container = one browser tree; after a single plain /crawl = two independent trees, permanent one idle.

Proposed fix

Keep the permanent browser, fix the match: build its config through the same path requests use (get_default_browser_config(), i.e. after enforce_egress), and compute DEFAULT_CONFIG_SIG from that. Alternatively/additionally, exclude the server-injected proxy_config from the pool signature, since the server sets it identically on every request.

Metadata

Metadata

Assignees

No one assigned

    Labels

    ⚙️ In-progressIssues, Features requests that are in Progress🐞 BugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions