[BUG] Embedded browser pane does not use the OS VPN / internal DNS
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Embedded browser pane does not use the OS VPN / internal DNS
Summary
The Claude Desktop / Claude Code embedded browser pane (the built-in browser driven by the preview/browser tools; preview_start returns apreview-local_... serverId) cannot reach hosts that are only resolvable through the machine's active VPN. Internal corporate hostnames fail to resolve in the embedded browser with ERR_NAME_NOT_RESOLVED (and follow-up subresource requests fail with ERR_BLOCKED_BY_CLIENT), even though the exact same machine, with the same VPN connected, resolves and loads those hosts fine via:
- the operating-system network stack (command line / PowerShell
Invoke-WebRequest), and - the real Chrome browser driven through the Claude in Chrome extension.
The embedded browser appears to use its own network/DNS context that bypasses the OS resolver — most likely Chromium Secure DNS (DNS-over-HTTPS) pointed at a public resolver — so split-tunnel VPN internal names never resolve. There is no documented setting to change this.
Environment
- Product: Claude Desktop (embedded browser pane / preview tools)
- OS: Windows 11 Pro (26xxx build)
- Network: corporate VPN active on the Windows host (split-tunnel; internal DNS served by the VPN)
- Target: an internal web app (React SPA) served over plain HTTP on a private
.tldnameTLD, reachable only through the VPN. - Host is redacted below as
http://<internal-host>/for this report.
Related
- GitHub issue #25513 ("Cowork incompatible with VPN") documents a different VPN problem (Hyper-V NAT routing blocking the Claude API), not embedded-browser DNS. No existing issue appears to cover embedded-browser DNS/VPN resolution.
What Should Happen?
Expected behavior
A browser running locally on the machine should inherit the host's network configuration — including the VPN's routes and DNS — the same way the OS and the user's normal Chrome do. Navigating the embedded browser to an internal host that is reachable over the active VPN should load the page.
Actual behavior
- Navigating to
http://<internal-host>/sometimes returns200 OKfor the top-level HTML document (likely a leaked/cached resolution), but every subresource of the same origin fails:
````
GET /some.js -> net::ERR_NAME_NOT_RESOLVED (DNS failure)
GET /some.js -> net::ERR_BLOCKED_BY_CLIENT
GET /static/js/<bundle>.js -> net::ERR_BLOCKED_BY_CLIENT
GET /static/css/<bundle>.css -> net::ERR_BLOCKED_BY_CLIENT
- Because the JS bundles never load, the SPA never mounts and the pane renders a blank white page.
- Navigating directly to a subresource URL (e.g.
/some.js) or to a sub-route (e.g./login) is denied ("navigation to ... was denied or failed").
The decisive signal is ERR_NAME_NOT_RESOLVED: this is a DNS resolution failure, not a routing/allowlist failure. The embedded browser cannot resolve the internal name at all.
Comparison across network contexts (same machine, same VPN, same moment)
| Path | Uses OS VPN + DNS? | Result on internal host |
|------|--------------------|-------------------------|
| Embedded browser pane | No (own network/DNS context) | Blank page — ERR_NAME_NOT_RESOLVED / ERR_BLOCKED_BY_CLIENT |
| OS command line (PowerShell Invoke-WebRequest) | Yes | 200 OK; full HTML + all assets downloaded successfully |
| Real Chrome via "Claude in Chrome" extension | Yes | SPA renders fully (login page loads normally) |
The only variable that changes the outcome is which network/DNS context the browser uses. This isolates the cause to the embedded browser's networking, not to the VPN, the server, or an allowlist.
Error Messages/Logs
GET /some.js -> net::ERR_NAME_NOT_RESOLVED (DNS failure)
GET /some.js -> net::ERR_BLOCKED_BY_CLIENT
GET /static/js/<bundle>.js -> net::ERR_BLOCKED_BY_CLIENT
GET /static/css/<bundle>.css -> net::ERR_BLOCKED_BY_CLIENT
Steps to Reproduce
Reproduction steps
- On a machine with a split-tunnel corporate VPN connected, pick an internal host that is only resolvable through that VPN.
- Confirm it resolves at the OS level (e.g.
Invoke-WebRequest http://<internal-host>/returns200). - In Claude Desktop, open the internal host in the embedded browser pane.
- 4. Observe: blank page; network log shows
ERR_NAME_NOT_RESOLVEDfor subresources. - Open the same host via the Claude in Chrome extension (real Chrome) → it loads fully. This confirms the difference is the embedded browser's network/DNS context, not the VPN or the server.
Claude Model
Opus
Is this a regression?
I don't know
Last Working Version
--
Claude Code Version
1.32885.1
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
PowerShell
Additional Information
Suspected root cause
Chromium enables Secure DNS (DNS-over-HTTPS) by default, which sends DNS queries to a public DoH resolver instead of the OS resolver. On a split-tunnel VPN, the internal DNS server is only consulted through the OS resolver, so:
- OS resolver (used by PowerShell and normal Chrome) → knows
<internal-host>→ resolves ✅ - Embedded browser's own DoH resolver → public resolver has no record of a private
.tldnamename →ERR_NAME_NOT_RESOLVED❌
A separate sandbox network namespace for the embedded browser could produce the same symptom. Either way, the embedded browser is not honoring the host's VPN-provided DNS.
Impact
- The embedded browser is unusable for any internal/corporate web app that requires a VPN — a very common enterprise scenario.
- Users cannot ask Claude to view, navigate, screenshot, or debug internal apps in the pane, even though Claude can reach the same host from the command line, which is confusing and looks like an intermittent failure.
- Current workaround (using the Claude in Chrome extension against the user's real Chrome) works but is not obvious and not equivalent to the built-in pane.
Suggested fixes / requests
- Make the embedded browser use the OS DNS resolver (respect the system's VPN-provided DNS), or
- Provide a documented setting/flag/environment variable to disable Chromium Secure DNS (DoH) in the embedded browser, or to point it at the system resolver, and/or
- Ensure the embedded browser inherits the host's VPN routes (no isolated network namespace that bypasses the VPN), and
- Surface a clearer error in the pane when a host fails to resolve (distinguish "DNS could not resolve" from a generic blank page), so the VPN/DNS cause is diagnosable.