mastra-ai/mastra · error · Error
Timeout resolving WebSocket URL from ${versionUrl} (10s)
Error message
Timeout resolving WebSocket URL from ${versionUrl} (10s) What it means
resolveWebSocketUrl enforces a hard 10-second timeout (AbortController) on the /json/version HTTP fetch. If the request aborts, the AbortError is converted into this descriptive timeout error. It means the CDP endpoint did not answer in time.
Source
Thrown at packages/core/src/browser/browser.ts:944
clearTimeout(timeoutId);
if (!response.ok) {
throw new Error(
`Failed to fetch CDP version info from ${versionUrl}: ${response.status} ${response.statusText}`,
);
}
const data = (await response.json()) as { webSocketDebuggerUrl?: string };
if (!data.webSocketDebuggerUrl) {
throw new Error(`No webSocketDebuggerUrl found in CDP version response from ${versionUrl}`);
}
this.logger.debug?.(`Resolved WebSocket URL: ${data.webSocketDebuggerUrl}`);
return data.webSocketDebuggerUrl;
} catch (error) {
clearTimeout(timeoutId);
if (error instanceof Error && error.name === 'AbortError') {
throw new Error(`Timeout resolving WebSocket URL from ${versionUrl} (10s)`);
}
throw error;
}
}
// Unknown protocol - return as-is and let the caller handle it
return url;
}
// ---------------------------------------------------------------------------
// Disconnection Detection & Error Handling
// ---------------------------------------------------------------------------
/**
* Error patterns that indicate browser disconnection.
* Used by isDisconnectionError() to detect external browser closure.
*/
protected static readonly DISCONNECTION_PATTERNS = [View on GitHub (pinned to 75dd419e61)
Solutions
- Confirm the endpoint responds with curl <versionUrl> before connecting.
- Ensure Chrome is fully started (wait for the port to accept connections) before connecting.
- Fix network/firewall rules so the host:port is reachable from the app.
- Retry with backoff after startup if the browser may still be booting.
Example fix
// before
await browser.connectToExternalCdp('http://chrome.internal:9222'); // chrome still starting
// after
await waitUntil(() => fetch('http://chrome.internal:9222/json/version').then(r => r.ok), { retries: 10, delayMs: 500 });
await browser.connectToExternalCdp('http://chrome.internal:9222'); Defensive patterns
Strategy: retry
Validate before calling
const port = new URL('http://host:9222').port;
await new Promise<void>((ok, fail) => {
const s = net.createConnection({ host: 'host', port: +port });
s.on('connect', () => { s.end(); ok(); });
s.on('error', fail);
s.setTimeout(3000, () => { s.destroy(); fail(new Error('CDP port not reachable')); });
}); Try / catch
for (let i = 0; i < 5; i++) {
try { await browser.connectToExternalCdp(url); break; }
catch (err) {
if (err instanceof Error && err.message.startsWith('Timeout resolving WebSocket URL') && i < 4) {
await new Promise(r => setTimeout(r, 2000)); // Chrome may still be starting
continue;
}
throw err;
}
} Prevention
- Wait for the debug port to accept TCP connections before attaching.
- Check firewall/security-group rules for the CDP port.
- Verify DNS resolution from the app container, not your laptop.
- Add readiness probes on containerized Chrome instances.
When it happens
Trigger: The http(s) CDP version URL is unreachable — wrong host/port, firewall dropping packets, Chrome not yet listening, DNS black-holing, or an overloaded endpoint — and fetch hangs until the 10s AbortController fires.
Common situations: Connecting before a containerized Chrome finished starting; pointing at a firewalled remote host where packets are silently dropped (hang instead of refuse); typos in hostnames causing long DNS timeouts.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Timeout resolving WebSocket URL from ${versionUrl} (10s)
- Failed to fetch CDP version info from ${versionUrl}: ${respo
- No webSocketDebuggerUrl found in CDP version response from $
- Request timed out after ${effectiveTimeout}ms
- ${this.latestError}
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/b8680a19e041fc70.
Report an issue: GitHub.