#353·pydoll

[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:

  1. Passing only host:port without credentials (then manually entering credentials in HTTP Auth dialog)
  2. Using the proxy without authentication

However, when trying to pass credentials programmatically via the proxy string, the connection always times out.

Steps to Reproduce

python
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

python
### 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:

  1. Auto-responding to proxy auth challenges with provided credentials
  2. 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

bash
[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)

python
options.add_argument('--proxy-server=user:pass@host:port')
# Result: Navigation times out after 30+ seconds

2. Using environment variables (NO EFFECT)

python
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 ignored

3. Manual auth handler with Page events (DOESN'T INTERCEPT PROXY AUTH)

python
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 challenges

4. Fetch domain auth handler (CAUSES ERRORS)

python
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 loop

5. Passing host:port only (WORKS BUT REQUIRES MANUAL INPUT)

python
options.add_argument('--proxy-server=host:port')
# Result: Works! But Chrome shows HTTP Auth dialog requiring manual credential entry
# This is not suitable for automation