[BUG] Embedded browser pane does not use the OS VPN / internal DNS

Status Open
Maintainer reply None cached
Activity 0 comments · opened Aug 20, 2026

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 a
preview-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 .tldname TLD, 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 returns 200 OK for 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

  1. On a machine with a split-tunnel corporate VPN connected, pick an internal host that is only resolvable through that VPN.
  2. Confirm it resolves at the OS level (e.g. Invoke-WebRequest http://<internal-host>/ returns 200).
  3. In Claude Desktop, open the internal host in the embedded browser pane.
  4. 4. Observe: blank page; network log shows ERR_NAME_NOT_RESOLVED for subresources.
  5. 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 .tldname name → 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

  1. Make the embedded browser use the OS DNS resolver (respect the system's VPN-provided DNS), or
  2. 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
  3. Ensure the embedded browser inherits the host's VPN routes (no isolated network namespace that bypasses the VPN), and
  4. 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.

View original on GitHub ↗