Skip to content

Commit 9d467d1

Browse files
committed
docs: add WSL2 + Windows remote Chrome CDP troubleshooting (#39407) (thanks @Owlock)
1 parent d3111fb commit 9d467d1

File tree

6 files changed

+252
-1
lines changed

6 files changed

+252
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ Docs: https://docs.openclaw.ai
3131
- Browser/CDP: rewrite wildcard `ws://0.0.0.0` and `ws://[::]` debugger URLs from remote `/json/version` responses back to the external CDP host/port, fixing Browserless-style container endpoints. (#17760) Thanks @joeharouni.
3232
- Browser/extension relay: wait briefly for a previously attached Chrome tab to reappear after transient relay drops before failing with `tab not found`, reducing noisy reconnect flakes. (#32461) Thanks @AaronWander.
3333
- Browser/extension relay: add `browser.relayBindHost` so the Chrome relay can bind to an explicit non-loopback address for WSL2 and other cross-namespace setups, while preserving loopback-only defaults. (#39364) Thanks @mvanhorn.
34+
- Docs/browser: add a layered WSL2 + Windows remote Chrome CDP troubleshooting guide, including Control UI origin pitfalls and extension-relay bind-address guidance. (#39407) Thanks @Owlock.
3435
- Context engine registry/bundled builds: share the registry state through a `globalThis` singleton so duplicated bundled module copies can resolve engines registered by each other at runtime, with regression coverage for duplicate-module imports. (#40115) thanks @jalehman.
3536

3637
## 2026.3.7

docs/docs.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1013,7 +1013,8 @@
10131013
"tools/browser",
10141014
"tools/browser-login",
10151015
"tools/chrome-extension",
1016-
"tools/browser-linux-troubleshooting"
1016+
"tools/browser-linux-troubleshooting",
1017+
"tools/browser-wsl2-windows-remote-cdp-troubleshooting"
10171018
]
10181019
},
10191020
{

docs/help/troubleshooting.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@ flowchart TD
290290

291291
- [/gateway/troubleshooting#browser-tool-fails](/gateway/troubleshooting#browser-tool-fails)
292292
- [/tools/browser-linux-troubleshooting](/tools/browser-linux-troubleshooting)
293+
- [/tools/browser-wsl2-windows-remote-cdp-troubleshooting](/tools/browser-wsl2-windows-remote-cdp-troubleshooting)
293294
- [/tools/chrome-extension](/tools/chrome-extension)
294295

295296
</Accordion>
Lines changed: 242 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,242 @@
1+
---
2+
summary: "Troubleshoot WSL2 Gateway + Windows Chrome remote CDP and extension-relay setups in layers"
3+
read_when:
4+
- Running OpenClaw Gateway in WSL2 while Chrome lives on Windows
5+
- Seeing overlapping browser/control-ui errors across WSL2 and Windows
6+
- Deciding between raw remote CDP and the Chrome extension relay in split-host setups
7+
title: "WSL2 + Windows + remote Chrome CDP troubleshooting"
8+
---
9+
10+
# WSL2 + Windows + remote Chrome CDP troubleshooting
11+
12+
This guide covers the common split-host setup where:
13+
14+
- OpenClaw Gateway runs inside WSL2
15+
- Chrome runs on Windows
16+
- browser control must cross the WSL2/Windows boundary
17+
18+
It also covers the layered failure pattern from [issue #39369](https://github.com/openclaw/openclaw/issues/39369): several independent problems can show up at once, which makes the wrong layer look broken first.
19+
20+
## Choose the right browser mode first
21+
22+
You have two valid patterns:
23+
24+
### Option 1: Raw remote CDP
25+
26+
Use a remote browser profile that points from WSL2 to a Windows Chrome CDP endpoint.
27+
28+
Choose this when:
29+
30+
- you only need browser control
31+
- you are comfortable exposing Chrome remote debugging to WSL2
32+
- you do not need the Chrome extension relay
33+
34+
### Option 2: Chrome extension relay
35+
36+
Use the built-in `chrome` profile plus the OpenClaw Chrome extension.
37+
38+
Choose this when:
39+
40+
- you want to attach to an existing Windows Chrome tab with the toolbar button
41+
- you want extension-based control instead of raw `--remote-debugging-port`
42+
- the relay itself must be reachable across the WSL2/Windows boundary
43+
44+
If you use the extension relay across namespaces, `browser.relayBindHost` is the important setting introduced in [Browser](/tools/browser) and [Chrome extension](/tools/chrome-extension).
45+
46+
## Working architecture
47+
48+
Reference shape:
49+
50+
- WSL2 runs the Gateway on `127.0.0.1:18789`
51+
- Windows opens the Control UI in a normal browser at `http://127.0.0.1:18789/`
52+
- Windows Chrome exposes a CDP endpoint on port `9222`
53+
- WSL2 can reach that Windows CDP endpoint
54+
- OpenClaw points a browser profile at the address that is reachable from WSL2
55+
56+
## Why this setup is confusing
57+
58+
Several failures can overlap:
59+
60+
- WSL2 cannot reach the Windows CDP endpoint
61+
- the Control UI is opened from a non-secure origin
62+
- `gateway.controlUi.allowedOrigins` does not match the page origin
63+
- token or pairing is missing
64+
- the browser profile points at the wrong address
65+
- the extension relay is still loopback-only when you actually need cross-namespace access
66+
67+
Because of that, fixing one layer can still leave a different error visible.
68+
69+
## Critical rule for the Control UI
70+
71+
When the UI is opened from Windows, use Windows localhost unless you have a deliberate HTTPS setup.
72+
73+
Use:
74+
75+
`http://127.0.0.1:18789/`
76+
77+
Do not default to a LAN IP for the Control UI. Plain HTTP on a LAN or tailnet address can trigger insecure-origin/device-auth behavior that is unrelated to CDP itself. See [Control UI](/web/control-ui).
78+
79+
## Validate in layers
80+
81+
Work top to bottom. Do not skip ahead.
82+
83+
### Layer 1: Verify Chrome is serving CDP on Windows
84+
85+
Start Chrome on Windows with remote debugging enabled:
86+
87+
```powershell
88+
chrome.exe --remote-debugging-port=9222
89+
```
90+
91+
From Windows, verify Chrome itself first:
92+
93+
```powershell
94+
curl http://127.0.0.1:9222/json/version
95+
curl http://127.0.0.1:9222/json/list
96+
```
97+
98+
If this fails on Windows, OpenClaw is not the problem yet.
99+
100+
### Layer 2: Verify WSL2 can reach that Windows endpoint
101+
102+
From WSL2, test the exact address you plan to use in `cdpUrl`:
103+
104+
```bash
105+
curl http://WINDOWS_HOST_OR_IP:9222/json/version
106+
curl http://WINDOWS_HOST_OR_IP:9222/json/list
107+
```
108+
109+
Good result:
110+
111+
- `/json/version` returns JSON with Browser / Protocol-Version metadata
112+
- `/json/list` returns JSON (empty array is fine if no pages are open)
113+
114+
If this fails:
115+
116+
- Windows is not exposing the port to WSL2 yet
117+
- the address is wrong for the WSL2 side
118+
- firewall / port forwarding / local proxying is still missing
119+
120+
Fix that before touching OpenClaw config.
121+
122+
### Layer 3: Configure the correct browser profile
123+
124+
For raw remote CDP, point OpenClaw at the address that is reachable from WSL2:
125+
126+
```json5
127+
{
128+
browser: {
129+
enabled: true,
130+
defaultProfile: "remote",
131+
profiles: {
132+
remote: {
133+
cdpUrl: "http://WINDOWS_HOST_OR_IP:9222",
134+
attachOnly: true,
135+
color: "#00AA00",
136+
},
137+
},
138+
},
139+
}
140+
```
141+
142+
Notes:
143+
144+
- use the WSL2-reachable address, not whatever only works on Windows
145+
- keep `attachOnly: true` for externally managed browsers
146+
- test the same URL with `curl` before expecting OpenClaw to succeed
147+
148+
### Layer 4: If you use the Chrome extension relay instead
149+
150+
If the browser machine and the Gateway are separated by a namespace boundary, the relay may need a non-loopback bind address.
151+
152+
Example:
153+
154+
```json5
155+
{
156+
browser: {
157+
enabled: true,
158+
defaultProfile: "chrome",
159+
relayBindHost: "0.0.0.0",
160+
},
161+
}
162+
```
163+
164+
Use this only when needed:
165+
166+
- default behavior is safer because the relay stays loopback-only
167+
- `0.0.0.0` expands exposure surface
168+
- keep Gateway auth, node pairing, and the surrounding network private
169+
170+
If you do not need the extension relay, prefer the raw remote CDP profile above.
171+
172+
### Layer 5: Verify the Control UI layer separately
173+
174+
Open the UI from Windows:
175+
176+
`http://127.0.0.1:18789/`
177+
178+
Then verify:
179+
180+
- the page origin matches what `gateway.controlUi.allowedOrigins` expects
181+
- token auth or pairing is configured correctly
182+
- you are not debugging a Control UI auth problem as if it were a browser problem
183+
184+
Helpful page:
185+
186+
- [Control UI](/web/control-ui)
187+
188+
### Layer 6: Verify end-to-end browser control
189+
190+
From WSL2:
191+
192+
```bash
193+
openclaw browser open https://example.com --browser-profile remote
194+
openclaw browser tabs --browser-profile remote
195+
```
196+
197+
For the extension relay:
198+
199+
```bash
200+
openclaw browser tabs --browser-profile chrome
201+
```
202+
203+
Good result:
204+
205+
- the tab opens in Windows Chrome
206+
- `openclaw browser tabs` returns the target
207+
- later actions (`snapshot`, `screenshot`, `navigate`) work from the same profile
208+
209+
## Common misleading errors
210+
211+
Treat each message as a layer-specific clue:
212+
213+
- `control-ui-insecure-auth`
214+
- UI origin / secure-context problem, not a CDP transport problem
215+
- `token_missing`
216+
- auth configuration problem
217+
- `pairing required`
218+
- device approval problem
219+
- `Remote CDP for profile "remote" is not reachable`
220+
- WSL2 cannot reach the configured `cdpUrl`
221+
- `gateway timeout after 1500ms`
222+
- often still CDP reachability or a slow/unreachable remote endpoint
223+
- `Chrome extension relay is running, but no tab is connected`
224+
- extension relay profile selected, but no attached tab exists yet
225+
226+
## Fast triage checklist
227+
228+
1. Windows: does `curl http://127.0.0.1:9222/json/version` work?
229+
2. WSL2: does `curl http://WINDOWS_HOST_OR_IP:9222/json/version` work?
230+
3. OpenClaw config: does `browser.profiles.<name>.cdpUrl` use that exact WSL2-reachable address?
231+
4. Control UI: are you opening `http://127.0.0.1:18789/` instead of a LAN IP?
232+
5. Extension relay only: do you actually need `browser.relayBindHost`, and if so is it set explicitly?
233+
234+
## Practical takeaway
235+
236+
The setup is usually viable. The hard part is that browser transport, Control UI origin security, token/pairing, and extension-relay topology can each fail independently while looking similar from the user side.
237+
238+
When in doubt:
239+
240+
- verify the Windows Chrome endpoint locally first
241+
- verify the same endpoint from WSL2 second
242+
- only then debug OpenClaw config or Control UI auth

docs/tools/browser.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,9 @@ Strict-mode example (block private/internal destinations by default):
649649
For Linux-specific issues (especially snap Chromium), see
650650
[Browser troubleshooting](/tools/browser-linux-troubleshooting).
651651

652+
For WSL2 Gateway + Windows Chrome split-host setups, see
653+
[WSL2 + Windows + remote Chrome CDP troubleshooting](/tools/browser-wsl2-windows-remote-cdp-troubleshooting).
654+
652655
## Agent tools + how control works
653656

654657
The agent gets **one tool** for browser automation:

docs/tools/index.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,9 @@ Browser tool:
531531
- `profile` (optional; defaults to `browser.defaultProfile`)
532532
- `target` (`sandbox` | `host` | `node`)
533533
- `node` (optional; pin a specific node id/name)
534+
- Troubleshooting guides:
535+
- Linux startup/CDP issues: [Browser troubleshooting (Linux)](/tools/browser-linux-troubleshooting)
536+
- WSL2 Gateway + Windows remote Chrome CDP: [WSL2 + Windows + remote Chrome CDP troubleshooting](/tools/browser-wsl2-windows-remote-cdp-troubleshooting)
534537

535538
## Recommended agent flows
536539

0 commit comments

Comments
 (0)