openclaw - 💡(How to fix) Fix [Bug]: Control UI service worker swallows top-level 401 from reverse-proxy auth, suppressing browser native credentials dialog

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

When OpenClaw Control UI is served behind an HTTP-auth reverse proxy (basic / digest / negotiate), the ui/public/sw.js network-first branch intercepts top-level navigation requests and forwards the upstream 401 WWW-Authenticate response via event.respondWith(). Per the Fetch and HTML specs, the browser only fires its native HTTP-auth challenge UI for responses delivered straight from the network — responses traversing a service worker are treated as opaque application responses. Result: on every full browser restart the user lands on a bare 401 Unauthorized page with no credentials dialog, and the only recovery is to clear the site data (which also unregisters the SW).

Root Cause

When OpenClaw Control UI is served behind an HTTP-auth reverse proxy (basic / digest / negotiate), the ui/public/sw.js network-first branch intercepts top-level navigation requests and forwards the upstream 401 WWW-Authenticate response via event.respondWith(). Per the Fetch and HTML specs, the browser only fires its native HTTP-auth challenge UI for responses delivered straight from the network — responses traversing a service worker are treated as opaque application responses. Result: on every full browser restart the user lands on a bare 401 Unauthorized page with no credentials dialog, and the only recovery is to clear the site data (which also unregisters the SW).

Fix Action

Fix / Workaround

Not applicable — bug is in the Control UI service worker dispatcher and is model-independent.

Code Example

HTTP/2 401
  alt-svc: h3=\":443\"; ma=2592000
  server: Caddy
  www-authenticate: Basic realm=\"restricted\"
  content-length: 0
RAW_BUFFERClick to expand / collapse

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

When OpenClaw Control UI is served behind an HTTP-auth reverse proxy (basic / digest / negotiate), the ui/public/sw.js network-first branch intercepts top-level navigation requests and forwards the upstream 401 WWW-Authenticate response via event.respondWith(). Per the Fetch and HTML specs, the browser only fires its native HTTP-auth challenge UI for responses delivered straight from the network — responses traversing a service worker are treated as opaque application responses. Result: on every full browser restart the user lands on a bare 401 Unauthorized page with no credentials dialog, and the only recovery is to clear the site data (which also unregisters the SW).

Steps to reproduce

  1. Deploy OpenClaw Gateway with gateway.auth.mode: "trusted-proxy" and controlUi.dangerouslyDisableDeviceAuth: true, bound to loopback.
  2. Put an HTTP basic_auth reverse proxy in front (here: Caddy 2.11.3 with basic_auth + reverse_proxy injecting X-Forwarded-User).
  3. In a normal Firefox profile, open the Control UI URL, complete the basic_auth dialog and any first-run setup, confirm the UI works.
  4. Fully close Firefox (pgrep -a firefox returns nothing).
  5. Reopen Firefox, navigate to the same Control UI URL.

Expected behavior

The browser receives the 401 Basic realm="restricted" response directly from the network and fires its native credentials dialog, as it does:

  • on the very first visit before the SW is installed, and
  • in a Firefox private window (no persisted SW) after restart.

Actual behavior

A bare 401 Unauthorized page is rendered with no credentials dialog. Firefox DevTools (Network tab) shows a single request GET <host>/openclaw/overview with Transferred: service worker, Status: 401. The exact code path is ui/public/sw.js falling into the else (network-first) branch around line 76, calling fetch(event.request) on the navigation, receiving the upstream 401, and returning it via event.respondWith().

The same flow works in a Firefox private window after restart (no SW persisted), which isolates the SW as the differentiator.

OpenClaw version

2026.5.22

Operating system

Ubuntu 26.04 LTS (x86_64)

Install method

npm global (openclaw CLI), gateway run via systemd user unit

Model

Not applicable — bug is in the Control UI service worker dispatcher and is model-independent.

Provider / routing chain

Not applicable — bug is in the browser ↔ reverse-proxy HTTP-auth handoff. Topology: browser → Caddy (basic_auth, reverse_proxy) → openclaw-gateway (loopback :18789).

Additional provider/model setup details

Reverse proxy: Caddy 2.11.3, network_mode: host, internal local CA, basic_auth matcher on /openclaw*, reverse_proxy 127.0.0.1:18789 with X-Forwarded-User: admin and X-Real-IP injection. Gateway auth.mode: trusted-proxy, controlUi.dangerouslyDisableDeviceAuth: true.

Logs, screenshots, and evidence

Pre-fix Firefox DevTools Network capture of the navigation request:

  • Request: GET <host>/openclaw/overview
  • Transferred: service worker
  • Status: 401 Unauthorized
  • Response headers (from DevTools → Copy Response Headers):
    HTTP/2 401
    alt-svc: h3=\":443\"; ma=2592000
    server: Caddy
    www-authenticate: Basic realm=\"restricted\"
    content-length: 0

Control case (same Caddy deployment, Firefox private window after restart): the same navigation is not SW-transferred, the 401 WWW-Authenticate response reaches the browser, and the native auth dialog fires.

Relevant spec / docs: MDN Using Service Workers and the Fetch spec — only network-direct responses trigger the UA HTTP auth-challenge UI.

Impact and severity

  • Affected: every reverse-proxy-fronted Control UI deployment that delegates authentication to an upstream HTTP-auth layer (controlUi.dangerouslyDisableDeviceAuth: true or equivalent) and uses Caddy / Traefik / nginx / Pomerium etc. with basic_auth, digest_auth, or negotiate in front of the gateway.
  • Severity: blocks UI access after browser restart. Recovery requires clearing site data, which unregisters the SW and wipes any persisted Control UI state.
  • Frequency: deterministic — reproduces on every full browser restart on the affected deployment (observed 100% of the time on the Caddy + Firefox setup above).
  • Consequence: operators with no other Control UI access path are effectively locked out until they go through the clear-site-data / re-pair dance.

Additional information

  • Reverse-proxy-fronted deployments are explicitly supported (see #71669 and #53274 for context on `trusted-proxy` / auth-bypass policies).
  • Related: #85939 already tracks side-effects of the Control UI SW caching policy on navigation.
  • Verification limited to Firefox latest stable; cross-browser behavior not exercised. The defect is browser-spec-coupled, so any UA that honors the Fetch-spec auth-challenge contract should be affected identically.
  • A candidate fix is proposed in PR #87077 (skip SW for `event.request.mode === "navigate"`); this issue is filed so the defect is tracked independently of the fix's review outcome.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

The browser receives the 401 Basic realm="restricted" response directly from the network and fires its native credentials dialog, as it does:

  • on the very first visit before the SW is installed, and
  • in a Firefox private window (no persisted SW) after restart.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - 💡(How to fix) Fix [Bug]: Control UI service worker swallows top-level 401 from reverse-proxy auth, suppressing browser native credentials dialog