White screen / "Cannot set properties of undefined (setting 'enableClientEncryption')" - Root cause and solution when using reverse proxy + HTTP Basic Auth
This article is summarized by LLM based on my conversations with LLM during the debugging process.
Symptom
- SilverBullet shows a white screen with only HTML skeleton loaded.
- Browser console error:
TypeError: Cannot set properties of undefined (setting 'enableClientEncryption') service_worker.jsfails to register with HTTP 401 or MIME typetext/html.- The issue is intermittent – sometimes the page loads after multiple refreshes, especially on faster devices/desktops.
My setup:
- SilverBullet v2.5.2 on Windows
- Nginx reverse proxy with HTTP Basic Auth
- CDN (EdgeOne) providing HTTPS edge, HTTP origin pull
- NSSM for Windows service
- Access: public internet → CDN → Nginx → SilverBullet
Key observation:
- Local access (http://localhost:3000) always works fine.
- Public access (https://my_domain) results in white screen / Service Worker registration failure.
- The issue is intermittent - more frequent on mobile devices, less frequent on desktop. Multiple refreshes sometimes succeed.
Root Cause
A race condition between Service Worker installation and the first data requests.
When SilverBullet loads:
- It tries to install the Service Worker.
- It does NOT wait for the Service Worker to be ready before sending critical requests (
.config,.fs/CONFIG.md, etc.).
If the Service Worker installs slowly (e.g., on mobile devices, or first visit), these data requests bypass the Service Worker and go directly to the reverse proxy (Nginx/Caddy). If the proxy requires HTTP Basic Auth, these requests return 401 because the browser hasn't provided credentials yet. The frontend code then fails to initialize, resulting in a white screen.
The "cache problem" is real – but the deeper issue is that the frontend logic doesn't await Service Worker readiness before making API calls.
Why it's intermittent
- Desktop / "Desktop mode" on mobile → faster Service Worker installation → wins the race → page loads.
- Mobile / slow network → slower installation → loses the race → white screen.
- Multiple refreshes → Service Worker may have installed in the background → subsequent loads succeed.
Solution
The fix makes Nginx automatically attach Basic Auth credentials when proxying to SilverBullet. This ensures that even if a request bypasses the Service Worker, the backend still receives valid credentials.
First, encode your username:password in Base64:
echo -n "username:password" | base64
Feel free to adjust the Base64 command syntax for your platform (base64 on Linux/macOS, certutil or PowerShell on Windows).
Then add to your Nginx location / block:
location / {
auth_basic "Restricted";
auth_basic_user_file .htpasswd;
# Forward credentials to backend automatically
proxy_set_header Authorization "Basic dXNlcm5hbWU6cGFzc3dvcmQ=";
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
# ... other proxy settings
}
3. Clear all caches and reset client
After updating Nginx, manually clear:
- Site data (Application → Storage → Clear site data)
- Cache storage
LLM also mentioned to do the following actions, but I'm not sure whether they would help:
https://your-domain.com/?resetClient=1
Manually clear Service Workers (chrome://serviceworker-internals/)
Why this works (LLM explanation)
- The Service Worker can be installed without authentication.
- The
Authorizationheader ensures all proxied requests (whether via Service Worker or direct) are authenticated. - No more race condition – the backend always sees valid credentials.
Result
As for me, although I can still see Error: Failed to register a ServiceWorker for scope ('https://*my_domain*/') with script ('https://*my_domain*/service_worker.js'): The script has an unsupported MIME type ('text/html'). error, I finally managed to edit my documents from public internet with my mobile phone.