microsoft/playwright · error · Error
Playwright extension did not connect within ${extensionConne
Error message
Playwright extension did not connect within ${extensionConnectionTimeout / 1000}s after opening the connect page. Make sure the extension is installed in the Chrome profile${profile} and PLAYWRIGHT_MCP_EXTENSION_TOKEN matches its token. What it means
`establishExtensionConnection` waits (against a deadline) for the Playwright Chrome extension to connect to the MCP CDP relay after the connect page is opened. If the extension has not connected and signaled readiness before `extensionConnectionTimeout` elapses, the wait times out and this error is thrown, telling the user to check the extension installation and token.
Source
Thrown at packages/playwright-core/src/tools/mcp/cdpRelay.ts:143
}
extensionEndpoint() {
return `${this._wsHost}${this._extensionPath}`;
}
async establishExtensionConnection(clientName: string) {
debugLogger('Establishing extension connection');
await this._openConnectPageInBrowser(clientName);
debugLogger('Waiting for incoming extension connection');
// Without a token the user has to approve the connection in the browser, which can take arbitrarily long.
const deadline = this._token ? monotonicTime() + extensionConnectionTimeout : 0;
const { timedOut } = await raceAgainstDeadline(async () => {
await this._extensionConnectionPromise;
await this._handler.ready();
}, deadline);
if (timedOut) {
const profile = this._profileDirectory ? ` "${this._profileDirectory}"` : '';
throw new Error(`Playwright extension did not connect within ${extensionConnectionTimeout / 1000}s after opening the connect page. Make sure the extension is installed in the Chrome profile${profile} and PLAYWRIGHT_MCP_EXTENSION_TOKEN matches its token.`);
}
debugLogger('Extension connection established');
}
private async _openConnectPageInBrowser(clientName: string) {
const mcpRelayEndpoint = `${this._wsHost}${this._extensionPath}`;
const url = new URL(`chrome-extension://${playwrightExtensionId}/connect.html`);
url.searchParams.set('mcpRelayUrl', mcpRelayEndpoint);
const client = {
name: clientName,
// Not used anymore.
version: undefined,
};
url.searchParams.set('client', JSON.stringify(client));
url.searchParams.set('protocolVersion', this._protocolVersion.toString());
if (this._token)
url.searchParams.set('token', this._token);
const href = url.toString();View on GitHub (pinned to 312030cdce)
Solutions
- Verify the Playwright extension is installed and enabled in the Chrome profile (path printed in the error if a custom profile is used).
- Ensure the `PLAYWRIGHT_MCP_EXTENSION_TOKEN` environment variable matches the extension's token.
- Check debug logs (`DEBUG=pw:mcp`) to confirm the relay endpoint URL and that the extension is attempting to connect.
- Make sure no proxy/firewall blocks the local WebSocket endpoint used by the extension.
- Retry on a faster machine or free CPU — slow profile startup can exceed the connection timeout.
Example fix
// before PLAYWRIGHT_MCP_EXTENSION_TOKEN=wrong-token npx @playwright/mcp // after PLAYWRIGHT_MCP_EXTENSION_TOKEN=<token-shown-by-extension> npx @playwright/mcp
Defensive patterns
Strategy: validation
Validate before calling
if (!isExtensionInstalledInProfile(profilePath)) {
throw new Error(`Install the Playwright extension in ${profilePath} before starting the MCP extension browser.`);
}
if (process.env.PLAYWRIGHT_MCP_EXTENSION_TOKEN && !tokenMatchesExtension(process.env.PLAYWRIGHT_MCP_EXTENSION_TOKEN)) {
throw new Error('PLAYWRIGHT_MCP_EXTENSION_TOKEN does not match the extension token.');
} Try / catch
try {
await establishExtensionConnection(deadline);
} catch (e) {
if (String(e.message).includes('extension did not connect within')) {
console.error('Check extension install and PLAYWRIGHT_MCP_EXTENSION_TOKEN; retrying once...');
await establishExtensionConnection(newDeadline);
} else throw e;
} Prevention
- Install and enable the extension in the Chrome profile before launching the MCP server.
- Keep PLAYWRIGHT_MCP_EXTENSION_TOKEN in sync with the extension's token.
- Verify with DEBUG=pw:mcp that the relay endpoint is reachable (no proxy/firewall blocking localhost WebSockets).
- Avoid resource-starved environments where profile startup exceeds the connection timeout.
When it happens
Trigger: Calling the MCP extension browser flow (`createExtensionBrowser` → `establishExtensionConnection`) where: the Playwright extension is not installed in the Chrome profile, the extension is installed but disabled, the extension's token does not match `PLAYWRIGHT_MCP_EXTENSION_TOKEN`, the extension fails to reach the relay's WebSocket endpoint, or the profile simply takes longer than the timeout to load.
Common situations: First-run setups where the extension was never installed into the profile; setting a custom `PLAYWRIGHT_MCP_EXTENSION_TOKEN` without updating the extension; firewalled/ proxied environments blocking the local WebSocket; slow CI machines exceeding the connection timeout.
Understand the failure class
Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Playwright Extension not found in "${userDataDir}". Install
- Extension not connected
- Unexpected WebSocket state: ${this._ws.readyState}
- Playwright Extension not found in "${profileDirectory ? path
- Timeout ${params.timeout}ms exceeded
AI-assisted analysis of microsoft/playwright@312030cdce (2026-09-07).
Data as JSON: /api/errors/2de979a8f2b53344.
Report an issue: GitHub.