SSO Proxies and CORS
When qui is behind an SSO proxy (Cloudflare Access, Pangolin, etc.), expired sessions can redirect API fetch() calls to the proxy's auth origin. Browsers block cross-origin redirects unless the proxy sends CORS headers, so you may see errors like "CORS request did not succeed" or "NetworkError". In normal same-origin setups, qui does not need any CORS configuration and keeps CORS disabled.
What qui does
- Detects likely SSO/CORS failures on
/api/*requests. - Performs a single top-level navigation so the SSO login can complete.
What you must configure
- Keep the auth flow same-origin if possible.
- Configure CORS on the SSO proxy (not in qui) for the auth endpoints.
- Allow credentials and handle
OPTIONSpreflight when required.
Optional qui allowlist
If another trusted website running in the user's browser must call qui from a different origin on the user's behalf, set an explicit allowlist:
QUI__CORS_ALLOWED_ORIGINS=https://panel.example.com
Only explicit origins are accepted (http(s)://host[:port]). Wildcards and path/query/fragment values are rejected.
If you still hit CORS errors after proxy configuration, capture the browser console error and open an issue.
Real-time updates and reverse-proxy buffering
qui pushes live torrent, stats, and instance-health updates to the UI over a
Server-Sent Events (SSE) stream at GET /api/stream (the RSS view uses a similar
stream). SSE is a long-lived HTTP response that the server flushes incrementally.
Most reverse proxies buffer responses by default, which holds events back and
makes the UI look frozen or stuck on "reconnecting" until the buffer fills.
If the dashboard and torrent list do not update in real time behind your proxy, disable response buffering and allow long-lived connections for the stream endpoint:
- nginx — for the qui location (or specifically
~ ^/api/stream):qui already sendsproxy_buffering off;proxy_cache off;proxy_read_timeout 1h;proxy_set_header Connection ""; # keep the upstream connection openproxy_http_version 1.1;X-Accel-Buffering: nostyle flushing, butproxy_buffering offis the reliable switch. - Traefik — SSE works without buffering by default; just ensure no
bufferingmiddleware (maxResponseBodyBytes/memResponseBodyBytes) is applied to the qui router. - Caddy —
reverse_proxystreams responses without buffering by default; no extra configuration is required.
Also make sure any idle/read timeout on the proxy is comfortably longer than a few
seconds. qui sends a heartbeat every 5s and the client reconnects automatically,
but an aggressive proxy timeout will cause unnecessary reconnects. Compression
middlewares should not be applied to text/event-stream responses.