[BUG] Browser pane blocks all subresources on private-network (RFC1918) LAN hosts with net::ERR_BLOCKED_BY_CLIENT - page never renders

Status Open
Reported on v2.1.233
Maintainer reply None cached
Activity 3 comments · opened Aug 17, 2026

Summary

In the Claude desktop app's built-in browser pane, loading any web app hosted on a private
LAN address renders a permanently blank / stuck page. The top-level HTML document fetches
successfully (HTTP 200), but every subresource — stylesheets, scripts, images, and
fetch()/XHR issued from page context — fails with net::ERR_BLOCKED_BY_CLIENT.

Because the requests are blocked client-side, they never reach the network, so there is
nothing to diagnose server-side. Any single-page app served from a LAN host is unusable.

Environment

| | |
|---|---|
| Claude desktop app | 1.30096.5 |
| Electron | 42.7.0 |
| Chromium | 148.0.7778.280 |
| Claude Code CLI | 2.1.233 |
| OS | macOS 26.6.2 (arm64) |
| Surface | Browser pane (mcp__Claude_Browser__* / preview pane), NOT the Claude in Chrome extension |
| Full UA | Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Claude/1.30096.5 Chrome/148.0.7778.280 Electron/42.7.0 Safari/537.36 |

Steps to reproduce

  1. Serve any static page with at least one CSS and one JS subresource from a machine on the

local network, reachable at an RFC1918 address (e.g. 10.0.0.5 or 192.168.1.5):

``bash
printf 'body{color:#0f0}\n' > style.css
printf 'document.getElementById("out").textContent="LOADED";\n' > app.js
printf '<!doctype html><link rel="stylesheet" href="style.css"><div id="out">BLOCKED</div><script src="app.js"></script>\n' > index.html
python3 -m http.server 8899 --bind 0.0.0.0
``

  1. From the Claude desktop app, open the browser pane at http://<lan-ip>:8899/index.html

(via preview_start, or the equivalent UI action).

  1. Inspect the console and network log for that tab.

Expected

The page renders. style.css and app.js load with HTTP 200, and the div reads LOADED.

Actual

The document loads (200) but the page is unstyled and the div still reads BLOCKED.
Every subresource request fails:

GET http://<lan-ip>:8899/style.css  [FAILED: net::ERR_BLOCKED_BY_CLIENT]
GET http://<lan-ip>:8899/app.js     [FAILED: net::ERR_BLOCKED_BY_CLIENT]

Diagnostic evidence

Observed against a real Sonatype Nexus Repository 3.95.1-01 instance on a LAN host
(RFC1918 address in 10.0.0.0/8, public DNS name, valid publicly-trusted TLS cert). All
30+ of its /static/** assets were blocked, so the ExtJS bootstrap never ran and the app
sat on "Initializing ..." indefinitely.

| Test | Result |
|---|---|
| curl https://<lan-host>/ from the same machine | 200, TLS verifies clean |
| curl https://<lan-host>/static/rapture/bootstrap.js | 200, application/x-javascript, 924 bytes |
| Browser pane: top-level document | 200, <title> renders correctly |
| Browser pane: same JS URL as a top-level navigation | Loads and displays fine |
| Browser pane: same JS URL as a <script> subresource | net::ERR_BLOCKED_BY_CLIENT |
| Browser pane: fetch() for that URL from page context | TypeError: Failed to fetch |
| Control — public site (en.wikipedia.org) in same pane | All CSS/JS/SVG subresources 200 |
| Control — unrelated Next.js app on a different LAN IP | All /_next/static/** chunks blocked |

The decisive pair is rows 4 and 5: the identical URL succeeds as a document and fails as
a subresource.
That isolates the trigger to request type combined with a private-network
destination, and rules out DNS, TLS, the reverse proxy, CORS, and the origin server.

The second control (a completely different stack — Next.js vs ExtJS — on a different LAN
IP, failing identically) rules out anything app-specific.

Related issues

  • #86362 (open) reports the identical failure signature — top-level document loads, all

same-origin subresources ERR_BLOCKED_BY_CLIENT — for hostnames mapped to 127.0.0.1
via /etc/hosts, starting ~2026-08-13. This report is the LAN-host variant: real
RFC1918 addresses resolved via ordinary DNS, no hosts-file involvement. Taken together,
the two suggest the pane blocks subresources whenever the destination doesn't resolve to
an approved/public address, regardless of how it resolves there.

  • #86228 (closed) requested user-approved local hostnames as trusted preview origins.

Scope notes

  • Confirmed on two hosts in 10.0.0.0/8 (HTTPS, valid public certs). Not yet tested:

192.168.0.0/16, 172.16.0.0/12, or plain-HTTP LAN origins.

  • Plain http://localhost:<port> / http://127.0.0.1:<port> preview was not re-tested in

this session; #86362 indicates loopback via hosts-file aliases is affected.

Impact

The browser pane cannot render any self-hosted LAN web UI — Nexus, GitLab, Proxmox,
Home Assistant, Unifi, internal dashboards, or a dev server bound to a LAN IP rather than
loopback. For homelab and on-prem workflows this makes the pane unusable, and the failure
mode is actively misleading: the page looks like a broken or hanging server rather than a
client-side block, which sends people debugging infrastructure that is working correctly.

Suggested handling

If blocking private-network subresources is deliberate (an SSRF or Private Network Access
style protection), then:

  1. It should apply consistently — blocking subresources while permitting top-level

navigation to the same URL is surprising and looks like a bug.

  1. The pane should surface a visible, attributable notice rather than failing silently, so

the cause isn't mistaken for a server fault.

  1. There should be an opt-in allowlist for trusted internal hosts (see #86228).

View original on GitHub ↗

3 Comments

bignay2000 · 13 days ago

Sonatype Nexus 3 from built in Claude Webbrowser

<img width="676" height="464" alt="Image" src="https://github.com/user-attachments/assets/f999b953-0fbd-4984-a5d3-f4363b8b56ba" />

Note this page loads fine in Safari and Google Chrome

dgohier · 12 days ago

Confirming and broadening the scope of this report from a real-world corporate VPN case (not localhost//etc/hosts dev setups).

We spent a full debugging session (mistakenly, at first) chasing this as a WAF/gateway config issue across our own internal platform (5 apps behind a VPN-only, SSO-gated Kubernetes ingress) before our SRE team ruled out any WAF/CDN change on their end and traced it to exactly this: Chromium's Private Network Access gating subresource requests (not navigations) to hosts resolving to a private IP, with the Browser pane unable to grant the PNA permission an embedded browser needs.

Repro details, matching this issue's diagnosis exactly:

  • GET / (top-level navigation) → 200, full SSR'd HTML
  • Every subsequent CSS/JS/asset request to the same host → net::ERR_BLOCKED_BY_CLIENT, no HTTP response ever sent
  • Confirmed via fetch() in the page's own JS console: fails identically regardless of path, request mode/credentials, burst vs. fully sequential timing, or authenticated session state
  • A localhost dev server running the identical app source works perfectly — only the private-IP-resolving host is affected
  • Reproduced across 6 unrelated internal apps at our org: several SvelteKit apps behind an internal K8s ingress (VPN-only, no CDN/WAF in front), plus two completely unrelated legacy apps (a React app, an ASP.NET app) also reached only over VPN — all fail identically
  • One internal app that does sit behind a public CDN/WAF (and thus resolves to a public IP) is unaffected — consistent with PNA being the actual mechanism, not any WAF/allowlist rule

No console message explains the block (unlike e.g. Mixed Content, which self-reports clearly) — the complete silence on why the request was blocked is what turned this into a multi-day investigation involving our whole platform SRE team before we found this issue. +1 on the reporter's suggestion #2 (surface a visible notice) at minimum, since the current silent failure actively misleads users into suspecting their own server/infra.

jedmitchell · 7 days ago

Corroborating with a discriminating test that narrows the mechanism.

Setup: internal HTTPS site on an RFC1918 address, reached over a VPN utun interface with split-horizon DNS (internal resolver). macOS, Claude Code desktop app, Browser pane.

Same evidence as reported: top-level documents return 200 (title renders, TLS fine — so DNS, VPN route, and connectivity all work inside the pane), while every same-origin /assets/*.js and *.css subresource fails net::ERR_BLOCKED_BY_CLIENT. SPA renders as a blank shell.

The narrowing test: navigating to one of the blocked asset URLs as a top-level navigation — same origin, same path, same session — loads the file successfully. So the filter is conditional on resource type / request context, not on the origin's address: navigations to the private origin are permitted, subresource fetches from it are killed. That rules out a plain private-address egress block and points at request-context policy in the pane's client-side filtering.

Impact: any LAN-hosted dashboard or staging app is unusable in the pane (blank shell), which breaks the preview/verify/annotate workflow for self-hosted and IoT development — the same pages work in standalone Chrome/Safari on the same machine. A per-origin "trust this internal site" affordance (or honoring an allowlist from settings) would unblock it.