dgtlmoon/changedetection.io · error · BrowserConnectError
Error while trying to connect the browser, Code {e.status_co
Error message
Error while trying to connect the browser, Code {e.status_code} (check your access, whitelist IP, password etc) What it means
puppeteer/pyppeteer fetcher got websockets.exceptions.InvalidStatusCode while connecting to the browser WebSocket endpoint; wrapped as BrowserConnectError with the HTTP status hint about access/whitelist/IP/password.
Source
Thrown at changedetectionio/content_fetchers/puppeteer.py:299
n = int(os.getenv("WEBDRIVER_DELAY_BEFORE_CONTENT_READY", 12)) + self.render_extract_delay
extra_wait = min(n, 15)
logger.debug(f"Extra wait set to {extra_wait}s, requested was {n}s.")
from pyppeteer import Pyppeteer
pyppeteer_instance = Pyppeteer()
# Connect directly using the specified browser_ws_endpoint
# @todo timeout
try:
logger.debug(f"[{watch_uuid}] Connecting to browser at {self.browser_connection_url}")
self.browser = await pyppeteer_instance.connect(browserWSEndpoint=self.browser_connection_url,
ignoreHTTPSErrors=True
)
logger.debug(f"[{watch_uuid}] Browser connected successfully")
except websockets.exceptions.InvalidStatusCode as e:
raise BrowserConnectError(msg=f"Error while trying to connect the browser, Code {e.status_code} (check your access, whitelist IP, password etc)")
except websockets.exceptions.InvalidURI:
raise BrowserConnectError(msg=f"Error connecting to the browser, check your browser connection address (should be ws:// or wss://")
except Exception as e:
raise BrowserConnectError(msg=f"Error connecting to the browser - Exception '{str(e)}'")
# more reliable is to just request a new page
try:
logger.debug(f"[{watch_uuid}] Creating new page")
self.page = await self.browser.newPage()
logger.debug(f"[{watch_uuid}] Page created successfully")
except Exception as e:
logger.error(f"[{watch_uuid}] Failed to create new page: {e}")
# Browser is connected but page creation failed - must cleanup browser
try:
await asyncio.wait_for(self.browser.close(), timeout=3.0)
except Exception as cleanup_error:
logger.error(f"[{watch_uuid}] Failed to cleanup browser after page creation failure: {cleanup_error}")
finally:View on GitHub (pinned to 5d9c7c6da7)
Solutions
- Verify the websocket URL includes required credentials/token (e.g. ws://host:3000/?token=...)
- Confirm host/port and that the browser service is up
- Whitelist the changedetection.io host IP with the browser provider
- Check for intercepting proxies that answer the WS upgrade with an error status
Example fix
# before browser_connection_url = "ws://browser:3000" # after browser_connection_url = "ws://browser:3000/?token=YOUR_TOKEN"
Defensive patterns
Strategy: try-catch
Validate before calling
import socket, urllib.parse
u = urllib.parse.urlparse(browser_url)
assert u.scheme in ('ws','wss') and u.hostname and u.port
socket.create_connection((u.hostname, u.port), timeout=5).close() # reachability pre-check Try / catch
try:
fetcher.fetch_page()
except BrowserConnectError as e:
if 'Code 40' in str(e): fix_credentials_or_whitelist()
else: raise Prevention
- Include auth tokens in the websocket URL for managed browser services
- Whitelist the changedetection.io host IP with the provider
- Pre-check TCP reachability before running checks
When it happens
Trigger: pyppeteer connecting to browser_connection_url and the endpoint answers with an unexpected HTTP status — 401/403 from an auth-protected browser, 404 wrong path/port, or a proxy in between.
Common situations: Browserless/cloud browser service requiring a token not in the URL; wrong port; firewall/NAT rejecting the WS handshake; IP not whitelisted on a managed browser service.
Related errors
- Error connecting to the browser - Exception '{str(e)}'
- Error connecting to the browser, check your browser connecti
- EmptyReply
- Non200ErrorCodeReceived
- Content Fetcher > xPath scraper failed. Please report this U
AI-assisted analysis of dgtlmoon/changedetection.io@5d9c7c6da7 (2026-08-27).
Data as JSON: /api/errors/12c0d49bf1dd6987.
Report an issue: GitHub.