[Bug]: Proxy with authentication causes navigation timeout
Author: masterchoCreated Jan 29, 2026Updated Mar 24, 2026
Labelsbug
Checklist before reporting
- I have searched for similar issues and didn't find a duplicate.
- I have updated to the latest version of pydoll to verify the issue still exists.
pydoll Version
Latest (tested with 2.9.2)
Python Version
3.10
Operating System
Windows
Bug Description
When using pydoll with an authenticated proxy (username:password@host:port), navigation commands timeout and hang indefinitely. The proxy works fine when:
- Passing only
host:portwithout credentials (then manually entering credentials in HTTP Auth dialog) - Using the proxy without authentication
However, when trying to pass credentials programmatically via the proxy string, the connection always times out.
Steps to Reproduce
import asyncio
from pydoll.browser.chromium import Chrome
from pydoll.browser.options import ChromiumOptions
async def test_proxy_auth():
options = ChromiumOptions()
# This works - proxy without auth (manual entry)
# options.add_argument('--proxy-server=192.168.1.100:8080')
# This HANGS - proxy with auth
options.add_argument('--proxy-server=username:[email protected]:8080')
browser = Chrome(options=options)
tab = await browser.start()
print("Starting navigation...")
try:
# This times out when using authenticated proxy
await tab.go_to("https://www.payback.de/, timeout=30)
print("Navigation successful")
except Exception as e:
print(f"Navigation failed: {e}")
finally:
await browser.stop()
asyncio.run(test_proxy_auth())Code Example
### Real-World Example with ChromiumOptions
This is how we're using pydoll with authenticated proxies:
import asyncio
from pydoll.browser.chromium import Chrome
from pydoll.browser.options import ChromiumOptions
from pydoll.commands import PageCommands
async def start_browser_with_proxy(proxy_string: str, headless: bool = True, disable_images: bool = False):
"""
Start browser with authenticated proxy.
proxy_string format: "username:password@host:port"
"""
options = ChromiumOptions()
# Add standard arguments
if headless:
options.add_argument("--headless=new")
if disable_images:
options.add_argument("--blink-settings=imagesEnabled=false")
# Disable automation detection
options.add_argument("--disable-blink-features=AutomationControlled")
options.add_argument("--disable-popup-blocking")
# Add proxy - this is where the issue occurs
options.add_argument(f"--proxy-server={proxy_string}")
print(f"[START] Creating browser with proxy: {proxy_string}")
browser = Chrome(options=options)
tab = await browser.start()
print("[START] Browser started")
return browser, tab
async def navigate_with_proxy(tab, url: str, timeout: float = 30):
"""
Navigate to URL using authenticated proxy.
This is where the hang occurs.
"""
print(f"[NAVIGATE] Going to: {url}")
# Send navigate command
navigate_task = asyncio.create_task(
tab._execute_command(PageCommands.navigate(url=url))
)
try:
# Wait for navigate with timeout
await asyncio.wait_for(navigate_task, timeout=timeout)
print("[NAVIGATE] Navigate command completed")
except asyncio.TimeoutError:
print(f"[NAVIGATE] Navigate command timed out after {timeout}s")
navigate_task.cancel()
raise
# Get page data
current_url = await tab.current_url
title = await tab.execute_script("return document.title;")
page_source = await tab.page_source
return current_url, title, page_source
# Usage
async def main():
# Test 1: Works fine without auth
print("\n=== Test 1: Proxy without auth ===")
browser1, tab1 = await start_browser_with_proxy("192.168.1.100:8080", headless=True, disable_images=True)
try:
url, title, source = await navigate_with_proxy(tab1, "https://www.example.com")
print(f"Success: {url} - {title}")
except Exception as e:
print(f"Failed: {e}")
finally:
await browser1.stop()
# Test 2: HANGS with auth
print("\n=== Test 2: Proxy with auth (HANGS) ===")
browser2, tab2 = await start_browser_with_proxy("user:[email protected]:8080", headless=True, disable_images=True)
try:
url, title, source = await navigate_with_proxy(tab2, "https://www.example.com", timeout=30)
print(f"Success: {url} - {title}")
except asyncio.TimeoutError:
print("TIMEOUT: Navigation hung with authenticated proxy")
except Exception as e:
print(f"Failed: {e}")
finally:
await browser2.stop()
asyncio.run(main())Expected Behavior
Navigation should complete successfully with authenticated proxy, either by:
- Auto-responding to proxy auth challenges with provided credentials
- Accepting credentials in the proxy string format
Actual Behavior
Navigation command times out and hangs indefinitely when proxy credentials are included in the proxy string.
Relevant Log Output
[START] Using proxy: username:[email protected]:8080
[START] Creating Chrome browser...
[START] Calling browser.start()...
[START] Browser started successfully!
[NAVIGATE] Going to: https://www.payback.de/
[NAVIGATE] Sending navigate command...
[NAVIGATE] Navigate command timed out at CDP level, continuing anyway...Additional Context
Workarounds Attempted
1. Passing credentials in proxy string (FAILS - TIMES OUT)
options.add_argument('--proxy-server=user:pass@host:port')
# Result: Navigation times out after 30+ seconds2. Using environment variables (NO EFFECT)
os.environ['CHROME_PROXY_USERNAME'] = 'username'
os.environ['CHROME_PROXY_PASSWORD'] = 'password'
options.add_argument('--proxy-server=host:port')
# Result: Still times out, env vars ignored3. Manual auth handler with Page events (DOESN'T INTERCEPT PROXY AUTH)
async def handle_auth(event):
await tab.handle_auth(username='user', password='pass')
await tab.on(PageEvent.JAVASCRIPT_DIALOG_OPENING, handle_auth)
# Result: Handler never called for proxy auth challenges4. Fetch domain auth handler (CAUSES ERRORS)
await tab.enable_fetch_events(handle_auth=False)
async def handle_auth_challenge(event):
await tab._execute_command({
"method": "Fetch.continueWithAuth",
"params": {
"requestId": event['params']['requestId'],
"authChallengeResponse": {
"response": "ProvideCredentials",
"username": "user",
"password": "pass"
}
}
})
await tab.on("Fetch.authRequired", handle_auth_challenge)
# Result: InvalidStateError in event loop5. Passing host:port only (WORKS BUT REQUIRES MANUAL INPUT)
options.add_argument('--proxy-server=host:port')
# Result: Works! But Chrome shows HTTP Auth dialog requiring manual credential entry
# This is not suitable for automationSource: autoscrape-labs/pydoll