Products
Datacenter proxies from $19/mo Rotating proxies from $49/mo ISP proxies from $33/mo Dedicated proxies from $3.50/mo UDP proxies from $5/mo Try proxies
Use cases
Data & scraping AI services Social media & messaging E-commerce & finance Media & entertainment Marketing & ads Automation & tools All use cases →
Pricing
Full pricing table All 20 locations Money-back guarantee
Resources
Blog Proxy API MCP server Setup guides FAQ For business About us Affiliate program
English
English Русский

How to set a proxy in Selenium WebDriver

Pointing Selenium at a proxy takes one line — a Chrome flag or the cross-browser Proxy class. The part that trips everyone up is authentication: Chrome ignores login:password@ in the proxy URL, and WebDriver can't click the login popup. This guide covers the setup in Python and Java, the working ways to authenticate, SOCKS5, and rotating proxies from a list.

Before you start: proxy details and ports

You'll need your proxy IP address and port. Both are listed in your Dashboard — open your active subscription to see the full connection details. The port depends on how you want to authenticate:

Authentication HTTP port SOCKS5 port Good for
IP whitelisting
no login required
8085 1085 The recommended option for Selenium — no authentication code at all
Username / password
credentials from your Dashboard
8080 1080 Machines whose IP changes — needs one of the workarounds below

With IP whitelisting, you first add your server's IP address to the whitelist in the Dashboard. After that, the proxy accepts requests from that machine with no credentials — which is exactly what Selenium wants.

The examples in this guide target Selenium 4:

pip install -U selenium

You usually don't need to install ChromeDriver separately anymore: starting with Selenium 4.6, Selenium Manager ships with the package and picks the right driver for your browser automatically.

Set a proxy in Chrome

The shortest route is the --proxy-server argument (the same flag works for Edge and other Chromium browsers):

Python

from selenium import webdriver options = webdriver.ChromeOptions() options.add_argument("--proxy-server=http://123.45.67.89:8085") driver = webdriver.Chrome(options=options) driver.get("https://api.ipify.org") print(driver.find_element("tag name", "body").text) # prints the proxy IP driver.quit()

Java

import org.openqa.selenium.Proxy; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.chrome.ChromeOptions; Proxy proxy = new Proxy(); proxy.setHttpProxy("123.45.67.89:8085"); proxy.setSslProxy("123.45.67.89:8085"); ChromeOptions options = new ChromeOptions(); options.setProxy(proxy); WebDriver driver = new ChromeDriver(options);

Python, Proxy class

The same cross-browser Proxy class is available in Python — this is the approach the current Selenium documentation shows for browser options:

from selenium import webdriver from selenium.webdriver.common.proxy import Proxy, ProxyType proxy = Proxy() proxy.proxy_type = ProxyType.MANUAL proxy.http_proxy = "123.45.67.89:8085" proxy.ssl_proxy = "123.45.67.89:8085" options = webdriver.ChromeOptions() options.proxy = proxy driver = webdriver.Chrome(options=options)

When you use the Proxy class, set both httpProxy and sslProxy to the same address. sslProxy is not a different kind of proxy — it's the proxy used for https:// URLs, and since almost every site is HTTPS now, leaving it empty sends almost all traffic around the proxy.

Set a proxy in Firefox

The same Proxy class works across browsers — in Python it attaches to the options object:

from selenium import webdriver from selenium.webdriver.common.proxy import Proxy, ProxyType proxy = Proxy() proxy.proxy_type = ProxyType.MANUAL proxy.http_proxy = "123.45.67.89:8085" proxy.ssl_proxy = "123.45.67.89:8085" options = webdriver.FirefoxOptions() options.proxy = proxy driver = webdriver.Firefox(options=options) driver.get("https://api.ipify.org") print(driver.find_element("tag name", "body").text) # prints the proxy IP driver.quit()

Proxy authentication: what actually works

This is the classic Selenium pain point: --proxy-server=http://login:password@ip:8080 looks right but doesn't work — Chrome ignores credentials embedded in a manual proxy address and shows the browser's HTTP authentication prompt instead. That prompt is not a DOM element of the page, so find_element() and regular Selenium actions can't reach it. The standard proxy capability offers no separate username and password fields for HTTP and HTTPS proxies either, so authentication needs a different mechanism. Three working options, in the order we'd recommend them:

1. IP whitelisting (port 8085) — no authentication at all. Whitelist your machine's IP in the Dashboard and use the plain setup from the sections above. This is the standard approach for scraping and test farms: no secrets in code, works in every browser and language.

2. Java: answer the login prompt through CDP. The Selenium 4 Java binding can register credentials for authentication challenges in Chromium browsers:

import org.openqa.selenium.HasAuthentication; import org.openqa.selenium.UsernameAndPassword; ((HasAuthentication) driver) .register(UsernameAndPassword.of("your-login", "your-password"));

3. Python: the Selenium Wire library. It proxies traffic through a local intermediary and handles the authentication for you:

from seleniumwire import webdriver # pip install selenium-wire options = { "proxy": { "http": "http://your-login:[email protected]:8080", "https": "http://your-login:[email protected]:8080", } } driver = webdriver.Chrome(seleniumwire_options=options)

Keep in mind that Selenium Wire is no longer actively maintained, so treat it as a stopgap — for anything long-lived, whitelisting is the cleaner path.

SOCKS5 proxies

Chrome takes SOCKS5 through the same flag with a different scheme, and the Proxy class has dedicated fields:

from selenium import webdriver options = webdriver.ChromeOptions() options.add_argument("--proxy-server=socks5://123.45.67.89:1085") driver = webdriver.Chrome(options=options) # or via the Proxy class (cross-browser): # proxy.socks_proxy = "123.45.67.89:1085" # proxy.socks_version = 5

The Selenium API does expose SOCKS credential fields (socks_username and socks_password), but don't rely on them: Chromium doesn't support SOCKS5 authentication, and other browsers' drivers implement these fields inconsistently. For reliable operation use port 1085 with IP whitelisting. For most Selenium work an HTTP proxy is the simpler choice.

You may have seen socks5h:// in curl or Python requests manuals — there the extra “h” makes the proxy resolve domain names instead of your machine, so DNS lookups don't leak outside the proxy. Chrome doesn't recognize that scheme and doesn't need it: per the Chromium documentation, with a plain socks5:// proxy name resolution is always done on the proxy side.

Loading proxies from a list and rotating them

With a proxy package, nobody types addresses into code by hand: export your full list from the Dashboard to a file — one IP:port per line, the field order and delimiter are configurable at export — and load it at the start of the script. One thing to know: WebDriver's standard tooling and the --proxy-server flag can't switch the proxy inside a running session, so the simplest and most reliable rotation pattern is a new driver per address (switching without a restart takes an extra layer: an extension, a PAC configuration, or a local intermediary proxy like Selenium Wire). With IP whitelisting (port 8085) the full script is:

from selenium import webdriver # proxies.txt — one address per line: 123.45.67.89:8085 with open("proxies.txt") as f: proxies = [line.strip() for line in f if line.strip()] for address in proxies: options = webdriver.ChromeOptions() options.add_argument(f"--proxy-server=http://{address}") driver = None try: driver = webdriver.Chrome(options=options) driver.get("https://example.com") # ... scrape ... except Exception as error: print(f"{address}: {error}") # a dead proxy won't stop the whole list finally: if driver is not None: driver.quit()

If your list runs on the credential ports (8080/1080), set the username and password once as constants — the addresses still come from the file. Chrome itself won't accept the credentials (see the authentication section), so in Python this goes through Selenium Wire:

from seleniumwire import webdriver # pip install selenium-wire LOGIN, PASSWORD = "your-login", "your-password" # proxies.txt — one address per line: 123.45.67.89:8080 with open("proxies.txt") as f: proxies = [line.strip() for line in f if line.strip()] for address in proxies: options = {"proxy": { "http": f"http://{LOGIN}:{PASSWORD}@{address}", "https": f"http://{LOGIN}:{PASSWORD}@{address}", }} driver = webdriver.Chrome(seleniumwire_options=options) driver.get("https://example.com") # ... scrape ... driver.quit()

In Java, keep the plain rotation loop and register the credentials once per driver via HasAuthentication (the CDP approach from the authentication section). And if you exported the list with credentials already embedded — lines like login:password@IP:port, the Dashboard export supports any field layout — drop the constants and use each line as is: f"http://{line}".

Our packages start at 100 IPs, so the list itself isn't the bottleneck — and when a target starts rate-limiting, refresh the list on request and re-export the file. Which of our proxy types fits Selenium best, with pricing and specs, is broken down on the proxies for Selenium page. If restarting the browser per IP is too slow for your workload, a rotating proxy flips the logic: you keep one gateway address in Selenium, and the exit IP rotates on every request.

Regular proxy settings in options travel to Selenium Grid with the new session and work with RemoteWebDriver unchanged. Authentication via HasAuthentication is a separate case: the interface is implemented directly by the Chromium drivers, not by the base RemoteWebDriver — so on Grid you may need an Augmenter, and the node must support CDP or WebDriver BiDi access.

If something doesn't work

The most common causes: ERR_TUNNEL_CONNECTION_FAILED or ERR_PROXY_CONNECTION_FAILED usually means the port doesn't match the authentication method (see the table) — or, on ports 8085/1085, that the machine's IP isn't whitelisted; a login popup at startup means the proxy expects credentials the browser can't supply — switch to whitelisting or use one of the authentication workarounds; and if HTTPS sites bypass the proxy while HTTP ones don't, you've set httpProxy but not sslProxy. If none of these is it, message us in live chat right on this page — we'll help you get connected.