anthropics / anthropics/claude-code
[BUG] Browser pane still blocks same-origin subresources on DDEV's *.ddev.site (public DNS → 127.0.0.1) after #86362 fix; *.test works
- Dominant language
- Python
- Stars
- 145k
- Forks
- 23.1k
- PR merge metrics
- PR metrics pending
Description
### Preflight Checklist
- [x] I have searched [existing issues](https://github.com/anthropics/claude-code/issues?q=is%3Aissue%20state%3Aopen%20label%3Abug) 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?
**Not a duplicate of #86362:** that issue was closed as completed on 2026-09-15; this reproduces on 2.110.1, built 2026-09-17.
In the Claude Desktop Browser pane (Code tab), a page served from a DDEV project's default hostname, `https://.ddev.site`, loads, but every request the page makes to a local origin fails with `net::ERR_BLOCKED_BY_CLIENT`, **including same-origin requests**. Requests from the same page to a public CDN succeed.
`*.ddev.site` is a public wildcard DNS record pointing at `127.0.0.1`. It is the default hostname for every DDEV project, so no DDEV site renders in the pane.
The same project served under a hosts-file `.test` name works for same-origin requests, even though the app stores identical approvals and IP pins for both origins.
Static probe page (source in Steps to Reproduce), same DDEV project and server; only the hostname changes:
| Page | Name resolves via | Same-origin fetch | Fetch to `:8026` (another local origin) | Fetch to public CDN |
|---|---|---|---|---|
| `https://.ddev.site/claude-probe.html` | public DNS | blocked | blocked | allowed |
| Same URL, with `127.0.0.1 .ddev.site` in `/etc/hosts`, app restarted | `/etc/hosts` | blocked | blocked | allowed |
| `https://.test/claude-probe.html` | `/etc/hosts` only | allowed (200) | blocked | allowed |
Ruled out:
- **Server, DNS, TLS:** `curl -skI https://.ddev.site` returns `HTTP/2 200`; `getent hosts .ddev.site` returns `127.0.0.1`; the document itself loads in the pane, and the only console error code is `net::ERR_BLOCKED_BY_CLIENT`.
- **Hosts file vs. DNS:** adding the `ddev.site` name to `/etc/hosts` changes nothing. With both names on the same line (`127.0.0.1 .test .ddev.site`, confirmed with `grep` before and after the run), `.test` works and `.ddev.site` stays blocked.
- **Stored approvals:** `~/.config/Claude/claude_desktop_config.json` lists both origins in `launchPreviewAllowedOrigins` and `launchPreviewPrivateNetworkReadOrigins`, and pins both to `127.0.0.1` in `launchPreviewPrivateNetworkReadPins`.
- **Outdated build:** 2.110.1 was the newest package in Anthropic's apt repository when tested.
### What Should Happen?
Same-origin subresources of an approved origin should load when the origin is `*.ddev.site`, as they do for `*.test`. Both origins are in the allowed lists and pinned to the same IP.
If blocking public domains that resolve to loopback is deliberate DNS-rebinding protection, an approved and pinned origin should be exempt, or there should be a user-controlled allowlist (#75289). As it stands, the pane can't render any DDEV project on its default hostname.
### Error Messages/Logs
```shell
Pane console on *.ddev.site pages (URLs not shown):
Failed to load resource: net::ERR_BLOCKED_BY_CLIENT
Probe on https://.ddev.site/claude-probe.html:
{
"href": "https://.ddev.site/claude-probe.html",
"sameOrigin": "TypeError: Failed to fetch",
"mailpit": "TypeError: Failed to fetch",
"publicCdn": "opaque"
}
Same URL with 127.0.0.1 .ddev.site in /etc/hosts (verified with grep before and after), app fully restarted:
{
"href": "https://.ddev.site/claude-probe.html",
"sameOrigin": "TypeError: Failed to fetch",
"mailpit": "TypeError: Failed to fetch",
"publicCdn": "opaque"
}
Probe on https://.test/claude-probe.html:
{
"href": "https://.test/claude-probe.html",
"sameOrigin": 200,
"mailpit": "TypeError: Failed to fetch",
"publicCdn": "opaque"
}
```
### Steps to Reproduce
1. Start any DDEV project (tested with DDEV v1.25.4). It is served at `https://.ddev.site`, which resolves to `127.0.0.1` through public DNS; `grep ddev.site /etc/hosts` finds nothing.
2. Save this as `claude-probe.html` in the project's docroot:
```html
claude-probe
running…
(async () => {
const probe = async (url, opts = {}) => {
try {
const r = await fetch(url, { cache: 'no-store', ...opts });
return r.type === 'opaque' ? 'opaque' : r.status;
} catch (e) { return String(e); }
};
document.getElementById('out').textContent = JSON.stringify({
href: location.href,
sameOrigin: await probe(location.href),
mailpit: await probe(`https://${location.hostname}:8026/`, { mode: 'no-cors' }),
publicCdn: await probe('https://cdn.jsdelivr.net/npm/jquery@3.7.1/package.json', { mode: 'no-cors' }),
}, null, 2);
})();
```
3. In Claude Desktop, open a Code session and open `https://.ddev.site/claude-probe.html` in the Browser pane. Approve the site if prompted, then read the JSON on the page.
4. **Result:** `sameOrigin` and `mailpit` are `TypeError: Failed to fetch` (console: `net::ERR_BLOCKED_BY_CLIENT`); `publicCdn` is `opaque`.
5. **Control:** give the project a hosts-file name. Create `.ddev/config.probe.local.yaml` containing `additional_fqdns: [".test"]` and run `ddev restart` (DDEV adds the `/etc/hosts` entry). Open `https://.test/claude-probe.html`: `sameOrigin` is `200`.
6. **Optional:** run `ddev hostname .ddev.site 127.0.0.1`, fully quit and relaunch Claude, and repeat step 3. It is still blocked.
`mailpit` probes DDEV's Mailpit on port 8026, used here as a second local origin.
### Claude Model
None
### Is this a regression?
I don't know
### Last Working Version
_No response_
### Claude Code Version
Claude Desktop 2.110.1 (ae8d2a) 2026-09-17T03:04:01.000Z (desktop app, Browser pane)
### Platform
Anthropic API
### Operating System
Ubuntu/Debian Linux
### Terminal/Shell
Other
### Additional Information
- **Environment:** Ubuntu 24.04.5 LTS (amd64); Claude Desktop from Anthropic's apt repository; DDEV v1.25.4 (HTTPS via the DDEV router and mkcert).
- **Earlier fix:** the 1.52386.0 release notes (2026-09-10) list a fix for private-network sites loading without styles, scripts, or data in the built-in browser. It does not cover this case.
- **Platform scope:** tested on Linux only. The build hash (`ae8d2a`) matches the macOS 2.110.1 Homebrew cask, so this is probably not Linux-specific, but that is untested.
- **Untested:** whether `*.test` works because it has no public DNS record or because of its TLD.
- **Console attribution:** console lines don't include URLs. The `:8026` failure on the `.test` page is attributed by elimination: it is the only failing request there, and `https://.test:8026/` loads with its CSS as a top-level navigation.
- **Cross-origin block:** the blocked request to `:8026` from the working `.test` page matches feature request #86487. It is included for completeness, not reported here.
- **Regression status:** unknown for `*.ddev.site`. Reporters on #86362 describe hosts-mapped domains working until mid-August 2026.
- **Related:** #86362, #87472, #92698, #86487, #90539, #75289. A DDEV user warned in #86362 that a fix could leave `*.ddev.site` blocked: https://github.com/anthropics/claude-code/issues/86362#issuecomment-5304725126
- **Workarounds for DDEV users:** add a `.test` name with `additional_fqdns` (same-origin requests work; cross-origin local requests such as a Vite dev server don't), or use Claude in Chrome.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by comparing the Browser pane's private-network handling with the completed fix in #86362, using the supplied DDEV probe and its *.ddev.site versus *.test results as the reproduction. Trace why approved, pinned same-origin requests receive net::ERR_BLOCKED_BY_CLIENT, then verify that *.ddev.site same-origin subresources load without weakening the reported protection for other local origins.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- html, javascript
- Domain
- desktop-dev, networking, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100