You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
desktop: local service on Tailscale receives unauthenticated requests #51075
Desktop 2.0.16 gets stuck on "Loading" and reports "Data migration failed" when its local service listens on a non-loopback address, such as a Tailscale IP.
The desktop's onBeforeSendHeaders filter only matches http://127.0.0.1/* and http://localhost/*, so requests to the discovered service address miss the Authorization header. The exact-origin check inside the handler already limits credentials to the registered service.
Plugins
Local notification plugin. The failure is in desktop request authentication, before the migration handler runs.
OpenCode version
2.0.16, official Linux x64 Desktop AppImage.
Steps to reproduce
Start the local OpenCode service bound to the machine's Tailscale IP, with authentication enabled.
Launch Desktop and let it discover the registered service.
Observe the loading screen, event-stream disconnects, and migration error.
Expected: Desktop authenticates to the discovered service, including on non-loopback addresses.
Screenshot and/or share link
Request evidence from the same machine:
Desktop GET /api/experimental/migration/v1: 401 Unauthorized
Authenticated GET to the same endpoint: 200 {"status":"completed"}
A local patch that expands the HTTP(S) request filter while preserving the exact-origin and trusted-renderer checks fixes loading and the startup migration check.
Thanks for the detailed report and the request evidence. Our automated environment can't run the Electron desktop app, so a maintainer with a desktop Linux setup will need to reproduce this.
The current code matches what you describe. In packages/desktop/src/main/windows/security.ts, wireRendererHeaders registers onBeforeSendHeaders only for http://127.0.0.1/* and http://localhost/*. The desktop app will still adopt a registered service on any address (it only rewrites 0.0.0.0 to 127.0.0.1). So when that service listens on a Tailscale or other non-loopback IP, the window's requests never reach the handler that adds the Authorization header, which explains the 401 you saw on /api/experimental/migration/v1. That filter has not changed on the current main line.
Still reproduces on 2.2.7 (official Linux x64 AppImage, Ubuntu 24.04, X11). In current builds it shows up as a "Signed out of this server — {server} no longer accepts this app's sign-in" screen instead of the loading/migration error, so I'm noting the new wording in case it helps others find this issue.
Setup: ~/.config/opencode/service.json sets hostname to the machine's Tailscale IP, so other devices on the tailnet can share the service. The desktop app adopts that service (v2 CLI background service ready … probed: true), then every renderer call to /api/info, /api/event, /api/config and /api/experimental/migration/v1 gets a 401. Capturing the renderer's traffic over CDP showed no Authorization header on those requests. The same endpoint returns 200 with Basic opencode:<password>.
Widening the onBeforeSendHeaders URL filter in the shipped app.asar fixes it right away. The exact-origin and top-level-renderer checks in the handler keep the credential scoped to the service. #60525 looks like the right fix. It would be great to get it reviewed, since #51076 was auto-closed for age.
Activity
opencodejr commentedon Oct 28, 2026
Thanks for the detailed report and the request evidence. Our automated environment can't run the Electron desktop app, so a maintainer with a desktop Linux setup will need to reproduce this.
The current code matches what you describe. In
packages/desktop/src/main/windows/security.ts,wireRendererHeadersregistersonBeforeSendHeadersonly forhttp://127.0.0.1/*andhttp://localhost/*. The desktop app will still adopt a registered service on any address (it only rewrites0.0.0.0to127.0.0.1). So when that service listens on a Tailscale or other non-loopback IP, the window's requests never reach the handler that adds theAuthorizationheader, which explains the 401 you saw on/api/experimental/migration/v1. That filter has not changed on the current main line.Related, for reference:
opencode serveTheCupcakeisalie commentedon Nov 13, 2026
Still reproduces on 2.2.7 (official Linux x64 AppImage, Ubuntu 24.04, X11). In current builds it shows up as a "Signed out of this server — {server} no longer accepts this app's sign-in" screen instead of the loading/migration error, so I'm noting the new wording in case it helps others find this issue.
Setup:
~/.config/opencode/service.jsonsetshostnameto the machine's Tailscale IP, so other devices on the tailnet can share the service. The desktop app adopts that service (v2 CLI background service ready … probed: true), then every renderer call to/api/info,/api/event,/api/configand/api/experimental/migration/v1gets a 401. Capturing the renderer's traffic over CDP showed noAuthorizationheader on those requests. The same endpoint returns 200 withBasic opencode:<password>.Widening the
onBeforeSendHeadersURL filter in the shippedapp.asarfixes it right away. The exact-origin and top-level-renderer checks in the handler keep the credential scoped to the service. #60525 looks like the right fix. It would be great to get it reviewed, since #51076 was auto-closed for age.