Skip to content

Misleading CDP "Empty reply from server" in WSL2 caused by portproxy self-loop (svchost/iphlpsvc), not Chrome #59209

@Owlock

Description

@Owlock

Bug type

Regression (worked before, now fails)

Beta release blocker

No

Summary

CDP endpoint returns curl: (52) Empty reply from server even when port 9222 appears as LISTENING, because a broken netsh portproxy self-loop rule (127.0.0.1:9222 -> 127.0.0.1:9222) causes svchost/iphlpsvc to own the port instead of Chrome — with no chrome.exe process running at all.

Steps to reproduce

  1. Have OpenClaw running in WSL2 on Windows 10, with Chrome configured as remote browser via CDP on port 9222.
  2. Over time (or after a restart), a stale or incorrect netsh portproxy rule accumulates, including a self-loop: 127.0.0.1:9222 -> 127.0.0.1:9222.
  3. Chrome is not running at all (tasklist /FI "IMAGENAME eq chrome.exe" returns no results).
  4. Run netstat -ano | findstr :9222 — port 9222 appears as LISTENING under PID 1400.
  5. Run tasklist /svc /FI "PID eq 1400" — PID is svchost.exe hosting iphlpsvc, not Chrome.
  6. Run curl.exe http://127.0.0.1:9222/json/version — returns curl: (52) Empty reply from server.
  7. Run curl.exe http://172.30.144.1:9222/json/version — same result.
  8. OpenClaw cannot list browser tabs.

Expected behavior

curl http://127.0.0.1:9222/json/version and curl http://172.30.144.1:9222/json/version return valid JSON from Chrome DevTools, and openclaw browser tabs lists the open tabs correctly.

Actual behavior

Both curl.exe http://127.0.0.1:9222/json/version and curl.exe http://172.30.144.1:9222/json/version return:

curl: (52) Empty reply from server

netstat -ano | findstr :9222 shows port LISTENING, but the PID belongs to svchost.exe (iphlpsvc), not chrome.exe. There is no Chrome process running (tasklist /FI "IMAGENAME eq chrome.exe" returns no results). OpenClaw cannot connect and lists no tabs.

Root cause confirmed: A stale portproxy self-loop rule (127.0.0.1:9222 -> 127.0.0.1:9222) was trapping traffic, making the port appear active but delivering empty responses.

OpenClaw version

2026.3.24 (cff6dc9)

Operating system

Windows 10 22H2 + WSL2 (Ubuntu) — Chrome 146.0.7680.178 on Windows, OpenClaw in WSL2

Install method

npm global (WSL2)

Model

openai-codex (OAuth)

Provider / routing chain

OpenClaw (WSL2) -> Chrome CDP remote browser (Windows) via netsh portproxy bridge at 172.30.144.1:9222 -> 127.0.0.1:9222

Additional provider/model setup details

No response

Logs, screenshots, and evidence

netstat output showing PID 1400 (svchost/iphlpsvc) owning port 9222:

TCP  127.0.0.1:9222   0.0.0.0:0   LISTENING  1400
TCP  172.30.144.1:9222  0.0.0.0:0  LISTENING  1400


tasklist confirming PID 1400 is NOT Chrome:

svchost.exe  1400  Appinfo, gpsvc, hns, IKEEXT, iphlpsvc, LanmanServer, ...


portproxy rules showing self-loop:

172.30.144.1  9222  127.0.0.1  9222
127.0.0.1     9222  127.0.0.1  9222   <-- INVALID SELF-LOOP


curl response (both endpoints):

curl: (52) Empty reply from server


After fix — tasklist confirming PID 1332 IS Chrome:

chrome.exe  1332  Console  1  156,764 KB


After fix — curl returning valid JSON:

{
  "Browser": "Chrome/146.0.7680.178",
  "Protocol-Version": "1.3",
  "webSocketDebuggerUrl": "ws://127.0.0.1:9222/devtools/browser/a72bd77b-4186-40aa-8910-773281c60102"
}


openclaw browser tabs output after full fix:

1. (untitled) about:blank   id: 8E72B32AC073F32D6CC73A70B25170B9

Impact and severity

  • Affected users: Any WSL2 user running OpenClaw with a remote Chrome CDP browser on Windows.
  • Severity: High — completely blocks browser automation; OpenClaw cannot connect or list tabs.
  • Frequency: Intermittent/recurring — stale portproxy rules accumulate after restarts or previous failed sessions.
  • Consequence: User loses the entire CDP→OpenClaw pipeline silently; the error (Empty reply from server) gives no indication that the root cause is a portproxy misconfiguration rather than a Chrome or OpenClaw bug.
  • Misleading factor: Port 9222 appears as LISTENING in netstat, making it easy to assume Chrome is running when it is not.

Additional information

Fix / Workaround (confirmed working)

Step 1: Remove all stale portproxy rules for port 9222

netsh interface portproxy delete v4tov4 listenaddress=127.0.0.1 listenport=9222
netsh interface portproxy delete v4tov4 listenaddress=172.30.144.1 listenport=9222
netsh interface portproxy show all

Step 2: Kill any stale Chrome processes and clean the debug profile

taskkill /F /IM chrome.exe
Remove-Item -Recurse -Force C:\chrome-debug
New-Item -ItemType Directory -Path C:\chrome-debug

Step 3: Launch Chrome with correct CDP flags (one line)

Start-Process "C:\Program Files\Google\Chrome\Application\chrome.exe" -ArgumentList "--remote-debugging-port=9222 --remote-debugging-address=127.0.0.1 --remote-allow-origins=* --user-data-dir=C:\chrome-debug about:blank"

Step 4: Verify Chrome is alive and CDP responds

tasklist /FI "IMAGENAME eq chrome.exe"
curl.exe http://127.0.0.1:9222/json/version

Step 5: Recreate the correct bridge rule (one direction only)

netsh interface portproxy add v4tov4 listenaddress=172.30.144.1 listenport=9222 connectaddress=127.0.0.1 connectport=9222

Step 6: Verify from WSL2 and reconnect OpenClaw

curl http://172.30.144.1:9222/json/version
curl http://172.30.144.1:9222/json/list
openclaw gateway restart
openclaw browser tabs

Suggestion for OpenClaw

It would be very helpful if OpenClaw could:

  • Detect when cdpUrl port is owned by svchost/iphlpsvc instead of a Chrome process
  • Warn the user that Chrome is not actually behind the endpoint
  • Suggest running tasklist + curl /json/version to verify before blaming the gateway or configuration

This would significantly improve DX for WSL2 users hitting this silent failure mode.

Key takeaway: LISTENING in netstat does NOT mean Chrome is healthy. Always verify the PID behind the port with tasklist /svc /FI "PID eq <pid>" before assuming Chrome is running.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingregressionBehavior that previously worked and now fails

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions