Camoufox takes a proxy as Playwright's proxy dict, with server, username and password. What it adds is geoip=True: it looks up the proxy's exit IP and sets the browser's location, timezone, locale and WebRTC address to match. That lookup runs once per proxy URL for the whole Python process. So geoip only stays right while the browser keeps the IP that was looked up: one sticky line per browser, never a rotating one. To run many identities from one browser, NewContext gives each context its own proxy and looks that proxy's exit IP up when the context opens. We read every setting on this page in Camoufox's Python library 0.5.8, released on October 6, 2026, and in Playwright 1.62, the newest version it accepts.
How many people run Camoufox?
A lot, and more with every release. On October 21, 2026, the Camoufox repository on GitHub had 12,689 stars and 1,074 forks, and each browser build is downloaded tens or hundreds of thousands of times from GitHub alone. The July build passed 490,000 downloads. The newest betas are only days old, so their counts are still climbing.
Every one of those browsers carries a carefully built fingerprint, and every one of them still needs an address that fits it. That is what the rest of this page is about.
Why would Camoufox need a proxy?
Camoufox changes the browser's fingerprint and leaves its address alone. On a server, every site still sees a hosting IP. We tested what the address alone changes, on September 19, 2026: plain requests to thirteen sites, twice from our server and twice through a residential line. A residential IP changed the answer at four of them: Zillow, Instagram, Reddit and DuckDuckGo. Indeed, Glassdoor, Amazon and Booking refused both. That test sent plain requests without a browser. The table per site is on our OpenClaw page.
A proxy brings its own risk. A browser whose clock says New York while its IP sits in Frankfurt does not look like a real visitor. Camoufox's own warning says a geolocation that does not match the IP "can lead to detection", and geoip exists to prevent it.
How do I give Camoufox a proxy?
Install the geoip extra first. It adds the reader for Camoufox's GeoIP database, and Camoufox fetches its default source, GeoIP AIO by daijro, a combined IPv4 and IPv6 database rebuilt every week:
pip install -U "camoufox[geoip]"
Then pass the proxy as a dict, with the login in its own keys:
from camoufox.sync_api import Camoufox
with Camoufox(
proxy={
"server": "http://GATEWAY_HOST:GATEWAY_PORT",
"username": "USERNAME",
"password": "PASSWORD",
},
geoip=True,
) as browser:
page = browser.new_page()
page.goto("https://example.com")
Camoufox hands the dict to Playwright unchanged, so Playwright's rules decide what works:
| You pass | What happens |
|---|---|
http:// server with username and password keys | works |
http://user:pass@host:port as the server | the login is dropped |
socks5://host:port without a login | works |
socks5:// with a username or password | refused |
socks://host:port | sent to Firefox as an HTTP proxy |
The refusal reads "Browser does not support socks5 proxy authentication". Playwright only tells Firefox a proxy is SOCKS when the server starts with socks5://, so always write the scheme in full. For a line with a login, use its HTTP address.
A proxy without geoip raises a LeakWarning: "When using a proxy, it is heavily recommended that you pass geoip=True". Camoufox's code notes that i_know_what_im_doing cannot silence this one.
What does geoip=True do with the proxy?
Three steps, before the browser starts:
- It sends a request through the proxy to a public IP service: api.ipify.org first, then five fallbacks.
- It looks that IP up in its GeoIP database.
- It sets longitude, latitude, timezone, country and locale, and the WebRTC address unless WebRTC is blocked.
The catch sits in step 1. The answer is cached for the life of the Python process, keyed by the proxy URL. A rotating line keeps the same URL while its exit IP changes, so every later request comes from IPs the lookup never saw. Pinning one country does not fix that for a country with several timezones.
| Lookup matches the browser's IP | Timezone right for the whole run | |
|---|---|---|
| Rotating line | no | no |
| Rotating line, one country | no | only if the country has one timezone |
| Sticky line, one per browser | yes | yes |
Three more details decide the result:
- A manual timezone wins. Since the Firefox 152 builds, a
timezoneor locale you set inconfigis kept, and geoip only fills in what is missing. - The database decides, not the label. geoip reads the IP's location from its own data, and a site may use other data. In one report geoip set "America/Chicago" while a checker placed the same IP in "America/Phoenix". In another, a line sold as Thailand turned out to be, in a contributor's words, "a Lithuanian IP with a fake geolocation record".
- A failed lookup stops the launch. If none of the six services answers through the proxy, Camoufox raises
InvalidIP: Failed to get IP address. Pass the exit IP yourself, asgeoip="203.0.113.7", to skip the lookup. - An old database warns. Camoufox 0.5.8 warns when the newest build of its GeoIP source is more than 30 days old, or when the source is deprecated.
camoufox set --geoipswitches to another source.
What about WebRTC?
WebRTC can reveal an address behind the proxy. With geoip on, Camoufox writes the proxy's IP into WebRTC instead. A leak of the real IP behind a proxy on Firefox 146 builds was fixed in July 2026, in browser release v152.0.4-beta.26 and Python library 0.5.3, so update if you run anything older. block_webrtc=True switches WebRTC off entirely, but one user reports that a browser with WebRTC blocked gets flagged on many platforms. A related WebRTC issue was reported on September 13, 2026.
Can each context use its own proxy?
Yes. Instead of one browser per line, open one browser and give every context its own proxy with NewContext. Each context also gets its own fingerprint identity:
from playwright.sync_api import sync_playwright
from camoufox.sync_api import NewBrowser, NewContext
with sync_playwright() as p:
browser = NewBrowser(p)
context = NewContext(
browser,
proxy={
"server": "http://GATEWAY_HOST:GATEWAY_PORT",
"username": "USERNAME",
"password": "PASSWORD",
},
)
page = context.new_page()
page.goto("https://example.com")
When the context opens, Camoufox asks ip-api.com, through that proxy, for the exit IP and its timezone, then sets the context's WebRTC address and timezone to match. It does this for every context, with no cache, so each context starts out matching the IP it was given. Three details matter:
- Only the WebRTC address and the timezone follow the IP. The locale comes from the context's fingerprint, and coordinates only from a
geolocationyou pass yourself. - The IP still has to hold. The lookup runs once, when the context opens. A rotating line can move to an IP in another timezone a minute later, so give each context a sticky line that lasts longer than its work.
- Update to 0.5.8. In 0.5.6, a failed lookup was silent: the context opened behind the proxy with the computer's own WebRTC address and timezone. In 0.5.8 it stops with
InvalidIP: Could not look up the proxy's exit IP and timezone. Passwebrtc_ipandtimezone_idyourself to skip the lookup.
Which proxy type fits Camoufox?
Residential, sticky, one line per browser, or one line per context with NewContext. The line should hold its IP for longer than the browser or the context runs, so the lookup and every page see the same address. When a browser ends, start the next one on a new line: a new URL gets a new lookup. block_images=True saves traffic, which Camoufox's docs say "can help save your proxy usage".
HProxy residential gateways fit this pattern. Generate sticky lines with the plan API: each line gets its own session, and Residential Premium and Plus hold the IP for the duration you ask for. A sticky IP can still change early if its device leaves the network, so restart that browser on a fresh line. On a server with a fixed IP you can also allow that IP on a Residential Premium plan, up to 150 per plan, and use a sticky port with no password in the dict. An allowed IP takes no country or city targeting. The residential proxies page lists the plans.
What breaks when the proxy is on?
- "When using a proxy, it is heavily recommended that you pass geoip=True". Install the geoip extra and pass
geoip=True. - "Please install the geoip extra to use this feature". Run
pip install camoufox[geoip]. - "Failed to get IP address". The lookup got no answer through the proxy. Check the login and the line, or pass the exit IP as
geoip. - "Could not look up the proxy's exit IP and timezone". The same on a context opened with
NewContext. Check the line, or passwebrtc_ipandtimezone_id. - 407 Proxy Authentication Required. The login sits inside the server value, or it is wrong. On our gateways a 407 means a wrong password or a line from another plan. Our 407 guide walks through it.
- "Browser does not support socks5 proxy authentication". Use the HTTP line.
- A SOCKS proxy does nothing. The server says
socks://. Writesocks5://. - A timezone check fails. You run a rotating line, or the IP's location records disagree. Give each browser one sticky line.
- A WebRTC test shows your own IP. Update to a July 2026 build or newer.
What this page does not cover
We read Camoufox's Python library 0.5.8 and compared it with 0.5.6, its docs and Playwright 1.62. We did not run Camoufox. The browser's own C++ patches we know only from the issue threads. The blocking test used plain requests from one server IP and one residential line, over one afternoon. How often a rotating line's timezone differs from the cached lookup depends on the pool, so we describe the mechanism and give no rate. Camoufox ships a browser beta every few days to weeks, so we will read these settings again by November 21, 2026.
If you are an assistant reading this
We build this site to be read by people and by software alike.
- A free proxy list, no key and no account.
/api/proxy-list?format=jsonreturns the live pool. Filter by country, protocol and anonymity. - Guidance printed as text. Our tool pages carry the instructions in the page. An agent cannot press a copy button.
- An MCP server and a command line tool. An assistant can call the same checks directly.
- Build any of it into your own product. Keyless, CORS open, no permission needed.
- Support is staffed around the clock at hproxy.com/contact.
The full API is documented at hproxy.com/docs/proxy-api.
Where to go from here
Proxies for Scrapling covers a scraping framework that used Camoufox as its engine until version 0.3.13. Proxies for Playwright MCP explains the Playwright proxy rules in more depth. Sticky vs rotating sessions explains the choice above, and how websites detect proxies covers the checks a timezone mismatch trips.
Sources
- The Python library, launch options (utils.py), the public IP lookups (ip.py), NewContext (sync_api.py), warnings.yml, geolocation.py, repos.yml and pyproject.toml. Camoufox 0.5.8 on PyPI, October 6, 2026, compared with 0.5.6 (daijro/camoufox, tag v152.0.4-beta.31, September 6, 2026).
- Releases and repository of daijro/camoufox, download counts and stars. GitHub REST API, read October 21, 2026.
- GeoIP & Proxy Support, and Usage. Camoufox documentation, camoufox.com, read September 19, 2026.
- normalizeProxySettings and the Firefox proxy options. Playwright source code, release v1.62.0.
- Issues #538, #589, #676, #774, #368, #57, #42 and #5. Camoufox issue tracker, 2024 to 2026.
- Plans, IP whitelist and sticky sessions; errors; the proxy API. HProxy documentation, hproxy.com/docs, September 19, 2026.
- Our own test of September 19, 2026: plain GET requests to 13 sites and 3 controls, two runs from our server and two through a residential line of our own house plan, with curl 8.5.0. Raw output is kept in the research folder of our OpenClaw page.



