Skip to content
Automation

Selenium Proxy Authentication: Why Chrome Ignores Your Credentials and What Actually Works

Selenium sets a proxy through browser options, and for an unauthenticated or IP-whitelisted proxy a single `--proxy-server` argument is enough. Username and password are the hard part: Chrome silently discards credentials in that flag, raises a native login dialog WebDriver cannot interact with, and the two classic fixes — Selenium Wire and a side-loaded extension — have both stopped being reliable. What still works is IP whitelisting, a small local forwarder that adds the credentials, or answering the challenge through the DevTools protocol.

seamless Team11 min readSeptember 28, 2026
  • selenium
  • python
  • automation
  • proxy authentication
A mechanical arm operating a single window panel whose routing line passes through a crimson relay block toward the horizon

This is the deep-dive for authenticated proxies. If your proxy is whitelisted and you only need the configuration, the Selenium integration page has the copy-paste version.

The baseline that works without credentials

python
from selenium import webdriver

options = webdriver.ChromeOptions()
options.add_argument("--proxy-server=http://PROXY_HOST:PROXY_PORT")

driver = webdriver.Chrome(options=options)
driver.get("https://api.ipify.org?format=json")
print(driver.find_element("tag name", "body").text)  # the proxy's IP
driver.quit()
Correct as long as the proxy does not ask for a password.

Add user:pass@ to that URL and nothing visibly changes — the browser opens, the page fails, and depending on the version you see a login prompt, a blank page or ERR_TUNNEL_CONNECTION_FAILED. Chrome treats proxy credentials as something a human types into a dialog, and that dialog lives outside the page where WebDriver has no reach.

Which approach to use

ApproachWorks in 2026Best forCatch
IP whitelistingYesFixed servers and CI runnersBreaks when your public IP changes
Local forwarderYesLaptops, Docker, Chrome and Firefox alikeOne extra process per identity
DevTools Fetch.continueWithAuthYes, Chromium onlyStaying inside PythonEvent handling via BiDi is still evolving
Side-loaded extensionOnly on Chromium / Chrome for TestingLegacy suitesBranded Chrome no longer loads it
Selenium WireNo—Archived; breaks on current Python and Selenium

Option 1: IP whitelisting

Register the public IP of the machine running Selenium in your proxy dashboard, and the proxy accepts its connections without a username or password. The baseline code above then works unchanged. This is the right answer for a VPS, a dedicated scraping box or a CI runner with a static egress address. See IP whitelisting for how it compares to credentials.

Whitelisting ties the proxy to your address, not your session. If a laptop moves between networks or a cloud instance is recycled onto a new IP, requests start failing with 407 and nothing in the error says why. Check what the proxy sees first.

Option 2: a local forwarder that adds the credentials

Run a tiny proxy on 127.0.0.1 with no authentication, and have it forward to the real proxy with credentials attached. Chrome talks to localhost without needing a password, and the forwarder handles the 407. GOST is a single static binary that does exactly this:

bash
# Listen locally without auth, forward upstream with auth
gost -L http://127.0.0.1:8080 -F http://USERNAME:PASSWORD@PROXY_HOST:PROXY_PORT
python
from selenium import webdriver

options = webdriver.ChromeOptions()
options.add_argument("--proxy-server=http://127.0.0.1:8080")
driver = webdriver.Chrome(options=options)
The browser never sees a credential, so there is nothing for it to drop.

The forwarder only relays the CONNECT tunnel — it does not decrypt HTTPS, so no certificate needs installing. Bind it to 127.0.0.1 rather than 0.0.0.0; an open unauthenticated relay on a public interface is an invitation for strangers to spend your bandwidth.

Option 3: answering the challenge through DevTools

Chromium can hand the authentication challenge to your code. Enabling the DevTools Fetch domain with handleAuthRequests makes the browser emit Fetch.authRequired when the proxy asks for credentials, and replying with Fetch.continueWithAuth supplies them. This keeps everything inside one Python process.

The catch is that it needs an event listener, and driver.execute_cdp_cmd can only send commands, not receive events. Recent Selenium 4 releases expose the listener through their BiDi and network APIs, but those are still marked as evolving. If you take this route, pin the Selenium version and add a test that loads an IP echo page through the proxy, so an upgrade cannot break it silently.

Why the old fixes stopped working

  • Selenium Wire intercepted traffic through its own embedded proxy and injected the credentials. The project was archived in early 2024 and its dependencies no longer install cleanly on current Python.
  • The generated extension — a Manifest file plus a webRequest.onAuthRequired listener, zipped and loaded with --load-extension — was the standard trick for years. Recent branded Chrome releases stopped honouring that flag. It still works on Chromium and Chrome for Testing, which is worth knowing if an old suite suddenly broke after a Chrome update.

Whitelist once, skip the workaround

ISP proxies from €1.80/IP with IP-whitelist or username authentication — one stable residential-registered address per browser. Residential from €1.20/GB.

See ISP proxies

Firefox

Firefox takes its proxy from preferences, set on the options object in Selenium 4. It also refuses to accept credentials this way, so the forwarder or whitelisting still applies.

python
from selenium import webdriver

options = webdriver.FirefoxOptions()
options.set_preference("network.proxy.type", 1)
options.set_preference("network.proxy.http", "127.0.0.1")
options.set_preference("network.proxy.http_port", 8080)
options.set_preference("network.proxy.ssl", "127.0.0.1")
options.set_preference("network.proxy.ssl_port", 8080)

driver = webdriver.Firefox(options=options)
The old firefox_profile= argument was removed in Selenium 4.10; preferences now go on the options.

Rotation: one identity per driver

A Chrome instance keeps its proxy for its whole lifetime, so rotation in Selenium means one driver per identity. With a gateway that assigns the exit from the username, give each worker its own forwarder and session tag:

python
import subprocess
import uuid
from selenium import webdriver

def start_identity(port: int):
    tag = uuid.uuid4().hex[:8]
    upstream = f"http://USERNAME-session-{tag}:PASSWORD@PROXY_HOST:PROXY_PORT"
    relay = subprocess.Popen(["gost", "-L", f"http://127.0.0.1:{port}", "-F", upstream])

    options = webdriver.ChromeOptions()
    options.add_argument(f"--proxy-server=http://127.0.0.1:{port}")
    return webdriver.Chrome(options=options), relay

driver, relay = start_identity(8081)
try:
    driver.get("https://api.ipify.org")
finally:
    driver.quit()
    relay.terminate()
Same session tag, same exit IP. New tag, new exit — without touching the browser configuration.

Keep the identity stable for the life of any logged-in task; switching exit mid-session is a stronger bot signal than any header. The trade-offs are covered in rotating vs sticky sessions.

A proxy does not hide WebDriver

A clean IP solves the network half of detection. Selenium-driven Chrome still sets navigator.webdriver, ships automation flags and has a recognisable fingerprint, and sites that check those will block you regardless of the exit. For account work, pair each proxy with a separate profile in an anti-detect browser; for scraping, Playwright is usually less work, since it handles proxy credentials natively and gives each context its own proxy.

Sources

Frequently asked questions

How do I use a proxy with username and password in Selenium?

Chrome ignores credentials in the --proxy-server argument, so either whitelist your machine's IP with the proxy provider, run a local forwarder on 127.0.0.1 that adds the credentials upstream, or answer the Fetch.authRequired DevTools event with Fetch.continueWithAuth.

Why does Chrome ignore proxy credentials in Selenium?

Chrome is designed to collect proxy credentials through a native login dialog, not from the command line. That dialog sits outside the page, so WebDriver cannot fill it, and the user:pass part of the proxy URL is discarded.

Is Selenium Wire still usable?

Not for new work. The project was archived in 2024 and no longer installs reliably on current Python and Selenium versions. A local forwarder such as GOST replaces its proxy-authentication role.

How do I rotate proxies in Selenium?

Each browser instance keeps one proxy, so start one driver per identity. With a gateway that selects the exit from the username, vary a session tag per driver, and keep it constant for the duration of any logged-in task.

Does Selenium support SOCKS5 proxies?

Yes. Chrome accepts --proxy-server=socks5://host:port and Firefox has network.proxy.socks preferences. Chrome does not support SOCKS5 authentication at all, so SOCKS5 with a password needs whitelisting or a forwarder.

Should I use Selenium or Playwright for proxy work?

Playwright accepts proxy credentials directly and supports a different proxy per browser context, which removes most of the work described here. Selenium remains the practical choice when you already maintain a large suite built on it.

SE
seamless Team
Proxy infrastructure

The seamless team runs residential, ISP and datacenter proxy infrastructure and writes these guides from day-to-day operational experience.

Ready to try seamless proxies?

Residential, ISP and datacenter proxies with no data expiry.

Browse Plans