- Fix qBittorrent login loops behind NGINX reverse proxies.
- Resolve 401, 403, HTTPS, Host header, and CSRF issues.
- Use safer subdomain, Docker, and Cloudflare troubleshooting steps.
- Quick Diagnosis Table
- Confirm qBittorrent Works Without NGINX
- Use a Correct NGINX Reverse-Proxy Configuration
- Fix Login Loops Caused By The Host Header
- Enable And Configure Reverse-Proxy Support In qBittorrent
- Fix HTTPS And X-Forwarded-Proto Problems
- Clear Stale qBittorrent Cookies And Site Data
- Check CSRF Protection And Origin Or Referer Headers
- Fix qBittorrent Served From An NGINX Subpath
- Check NGINX Logs And qBittorrent Logs
- Docker-Specific Checks
- Cloudflare Or Another Proxy In Front Of NGINX
- Firewall And Authentication Rate-Limit Issues
- Recommended Troubleshooting Order
- FAQ
- Conclusion
If the qBittorrent WebUI login page loads through NGINX but the correct username and password simply return you to the login screen, the reverse proxy is probably reaching qBittorrent successfully. The failure is usually not a basic connectivity problem. It is more often caused by a mismatched Host header, missing forwarded HTTPS information, stale browser cookies, qBittorrent reverse-proxy trust settings, CSRF checks, or a fragile subpath configuration.
This guide focuses specifically on qBittorrent and qBittorrent-nox authentication problems behind NGINX. It assumes you can edit your NGINX and qBittorrent configuration, but it does not assume you are a system administrator. It does not cover general WebUI installation, password recovery, or disabling security controls as a permanent workaround.

Start with free Canva bundles
Browse the freebies page to claim ready-to-use Canva bundles, then get 25% off your first premium bundle after you sign up.
Free to claim. Canva-ready. Instant access.
1. Quick Diagnosis Table
Use this table to match the symptom you see with the most likely cause and the first fix worth trying.
| Symptom | Most likely cause | First fix to try |
|---|---|---|
| Login page keeps reappearing | Session cookie, Host header, CSRF, or proxy-trust mismatch | Forward the correct Host and scheme, then clear site cookies |
| 401 Unauthorized | Authentication request rejected, stale session, wrong credentials, or CSRF failure | Confirm direct local login, then inspect browser Network requests |
| 403 Forbidden | Host validation, CSRF protection, IP ban, or reverse-proxy trust issue | Check qBittorrent logs and trusted proxy settings |
| Invalid Host header | NGINX is forwarding an unexpected Host value | Use proxy_set_header Host $host; or configure the accepted domain |
| Login works by local IP but not by domain | Public hostname, cookies, HTTPS, or Host validation mismatch | Proxy the public hostname correctly and clear cookies for both URLs |
| Login works over HTTP but not HTTPS | NGINX terminates TLS but does not pass the original scheme | Set X-Forwarded-Proto $scheme and use the HTTPS URL consistently |
| WebUI loads but buttons or API requests fail | CSRF, subpath, Origin, Referer, or API path mismatch | Open browser developer tools and inspect failed API calls |
| Login fails only from a subdirectory | Incorrect path rewriting, trailing slash, or cookie path issue | Test a dedicated subdomain first, then fix subpath proxying |
| Login stopped working after an update | Changed qBittorrent security behavior or stricter proxy validation | Review WebUI security and reverse-proxy settings for your version |
2. Confirm qBittorrent Works Without NGINX
Before changing NGINX, confirm that qBittorrent itself can accept a login. This separates qBittorrent-side problems from reverse-proxy problems.
2.1 Test the local WebUI address
From a machine on the same network, try opening the qBittorrent WebUI directly. For example:
http://192.168.1.50:8080/If you are on the server running qBittorrent, you can test from the server itself:
http://127.0.0.1:8080/Use the actual WebUI port configured in qBittorrent. Do not assume it is 8080 if you changed it.
2.2 Test with curl
A simple curl request can confirm whether the WebUI is reachable locally:
curl -I http://127.0.0.1:8080/You may see a normal HTTP response such as 200, 401, or a redirect depending on the qBittorrent version and endpoint. The important point is that the server responds. If curl cannot connect, NGINX will not be able to proxy to it either.
2.3 Confirm the listening address and port
On Linux, check listening ports with:
sudo ss -ltnp | grep -E 'qbittorrent|8080'If qBittorrent is listening only on 127.0.0.1:8080, NGINX on the same host can usually reach it through localhost. If NGINX is in a separate Docker container or another machine, localhost will not work. In that case, NGINX must reach qBittorrent through the correct container name, bridge address, LAN address, or internal service address.
Also make sure the internal qBittorrent WebUI port is not the same thing as your public HTTPS port. NGINX commonly listens on public port 443 and proxies to qBittorrent on an internal port such as 8080.
2.4 Interpret the result
If direct local login fails, your problem is probably inside qBittorrent: credentials, WebUI configuration, service state, profile permissions, or a temporary ban. Password reset and account recovery are outside the scope of this article, but you should at least confirm that the username and password are correct.
If direct login works but proxied login fails, continue with the reverse-proxy fixes below.
3. Use a Correct NGINX Reverse-Proxy Configuration
For a dedicated qBittorrent subdomain such as https://torrent.example.com/, start with a clean, predictable NGINX server block. The exact certificate paths and upstream port will differ on your system.
server {
listen 80;
server_name torrent.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name torrent.example.com;
ssl_certificate /etc/letsencrypt/live/torrent.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/torrent.example.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_read_timeout 300;
proxy_send_timeout 300;
proxy_connect_timeout 60;
}
}In this root-domain example, proxy_pass http://127.0.0.1:8080; sends requests to a qBittorrent WebUI running on the same host. Because the location is / and the proxy_pass has no extra URI path, NGINX forwards the original path cleanly.
The Host header tells qBittorrent which public hostname the user requested. The X-Real-IP and X-Forwarded-For headers preserve the client IP chain. The X-Forwarded-Proto header tells qBittorrent that the original browser request used HTTPS, even though the internal upstream request from NGINX to qBittorrent may be plain HTTP. The X-Forwarded-Host header is useful for applications that check the original external host separately.
After editing NGINX, always test and reload:
sudo nginx -t
sudo systemctl reload nginx
4. Fix Login Loops Caused By The Host Header
A common mistake is forwarding the internal upstream host instead of the public domain. For example, this is usually wrong for a public subdomain setup:
proxy_set_header Host 127.0.0.1:8080;It tells qBittorrent that the browser requested 127.0.0.1:8080, even though the user is actually visiting torrent.example.com. That mismatch can break host-header validation, cookies, redirects, and CSRF checks.
Use one of these instead:
proxy_set_header Host $host;or, if you specifically need to preserve a port from the original request:
proxy_set_header Host $http_host;For most standard HTTPS sites on port 443, $host is the cleaner choice. It normalizes the hostname and avoids some malformed Host values. $http_host passes the browser's Host header more literally, including a port if present.
4.1 Public hostname versus internal upstream address
The public hostname is what the browser uses, such as torrent.example.com. The internal upstream address is how NGINX reaches qBittorrent, such as 127.0.0.1:8080, qbittorrent:8080, or 192.168.1.50:8080. These are not interchangeable. The upstream belongs in proxy_pass. The public hostname belongs in the forwarded Host header.
4.2 Invalid Host header
If qBittorrent displays an Invalid Host header error, it means the WebUI rejected the Host value it received. The fix is usually to forward the real public hostname and configure qBittorrent to accept that hostname through the appropriate WebUI security or reverse-proxy setting.
Do not treat disabling host-header validation as the final solution. Host validation exists to reduce host-header abuse. Menu names and configuration keys vary by qBittorrent version, so look for the equivalent WebUI security, host validation, or reverse-proxy setting in your installed version, then add the correct public domain or configure NGINX to pass it correctly.
5. Enable And Configure Reverse-Proxy Support In qBittorrent
Some qBittorrent versions include explicit settings for reverse-proxy support, trusted proxies, or WebUI host validation. These settings help qBittorrent decide whether to trust headers such as X-Forwarded-For and X-Forwarded-Proto.
If your version has a reverse-proxy support option, enable it only for your actual proxy path. Then trust only the NGINX server or container that is allowed to send forwarded headers.
5.1 Which IP should be trusted?
The correct trusted proxy address depends on deployment:
- Same host without Docker: often
127.0.0.1if NGINX connects through loopback. - Separate LAN server: the LAN IP address of the NGINX server.
- Docker Compose network: the NGINX container IP or, if the application supports CIDR ranges and you understand the risk, the specific Docker network subnet.
- Reverse proxy container: the IP address qBittorrent sees as the source of proxied requests.
Avoid trusting every IP range, such as 0.0.0.0/0, unless you are performing a very short diagnostic test in an isolated environment. If any client can spoof forwarded headers, qBittorrent may make security decisions using untrusted client-supplied data.
After changing qBittorrent settings through the WebUI or configuration file, restart qBittorrent if your version requires it. With a systemd service, that is commonly:
sudo systemctl restart qbittorrent-noxThe exact service name may differ.
6. Fix HTTPS And X-Forwarded-Proto Problems
When NGINX terminates HTTPS, the browser talks to NGINX using HTTPS, but NGINX may talk to qBittorrent using internal HTTP. That is normal. The important part is telling qBittorrent what the original browser scheme was.
Include this header in the qBittorrent location block:
proxy_set_header X-Forwarded-Proto $scheme;If this header is missing or wrong, qBittorrent may believe the public request is HTTP. That can contribute to incorrect redirects, rejected CSRF checks, or cookie behavior that does not match the browser's HTTPS session.
Use one public URL consistently while testing, preferably the final HTTPS URL:
https://torrent.example.com/Avoid alternating between http://, https://, the local IP, and the domain in the same browser session. Mixed access can leave old cookies and session state attached to different hosts or schemes.
7. Clear Stale qBittorrent Cookies And Site Data
Old browser data can preserve a broken host, protocol, path, or session state even after you fix NGINX. This is especially common after changing from HTTP to HTTPS, switching from an IP and port to a domain, moving the WebUI under a subpath, or changing qBittorrent security settings.
Use this exact sequence:
- Open the WebUI in a private or incognito browser window.
- If login works there, clear cookies and site data for the qBittorrent domain in your normal browser profile.
- Close every tab that still uses the old local IP, old hostname, old port-based URL, or old HTTP URL.
- Open only the final reverse-proxy URL, such as
https://torrent.example.com/. - Log in again and check whether the session persists after refreshing the page.
Clearing cookies is not a substitute for fixing headers, but it prevents old sessions from hiding the result of your configuration changes.
8. Check CSRF Protection And Origin Or Referer Headers
qBittorrent's CSRF protection can reject login or API requests when the request appears to come from the wrong host, scheme, or path. NGINX does not need to invent Origin or Referer headers, but it must preserve the public Host and scheme so qBittorrent can evaluate requests consistently.
8.1 Use browser developer tools
Open the browser developer tools, go to the Network tab, submit the login form, and look for failed requests. Pay attention to:
- Status codes such as
401or403. - POST requests to login or API endpoints.
- The request URL shown by the browser.
- The Origin and Referer request headers.
- Redirects that change from HTTPS to HTTP or from the domain to an IP address.
The Origin and Referer should correspond to the public WebUI URL you are using. If the browser is on https://torrent.example.com/ but a request is redirected to http://127.0.0.1:8080/ or another hostname, fix the NGINX Host and forwarded-protocol headers first.
8.2 Do not permanently disable CSRF protection
Temporarily disabling CSRF protection can be useful as a short diagnostic test if your qBittorrent version provides that option and you are working in a controlled environment. It should not be the final fix. Re-enable CSRF protection immediately and correct the proxy configuration that caused the mismatch.

9. Fix qBittorrent Served From An NGINX Subpath
Serving qBittorrent from a subpath such as https://example.com/qbittorrent/ is more error-prone than using a dedicated subdomain. Web applications often assume they live at the root path. Authentication can fail when API URLs, redirects, static assets, or cookie paths do not line up with the prefix.
If possible, use a dedicated subdomain such as https://torrent.example.com/. It avoids most path rewriting and cookie-path ambiguity.
9.1 Subpath example
If you must use a subpath, keep trailing slashes consistent. One plausible NGINX pattern is:
location = /qbittorrent {
return 301 /qbittorrent/;
}
location /qbittorrent/ {
proxy_pass http://127.0.0.1:8080/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Prefix /qbittorrent;
proxy_read_timeout 300;
proxy_send_timeout 300;
}In this example, the trailing slash on proxy_pass http://127.0.0.1:8080/; tells NGINX to replace the matching /qbittorrent/ prefix with / when forwarding to qBittorrent. That means a browser request for /qbittorrent/api/v2/... is sent upstream as /api/v2/....
Exact requirements may differ by qBittorrent version and deployment. If login works on a subdomain but fails under a subpath, the issue is almost certainly path rewriting, cookie path, CSRF, or relative URL handling. Test the root subdomain first so you know qBittorrent and authentication are working before debugging the subpath.
10. Check NGINX Logs And qBittorrent Logs
Logs usually show whether the login request reaches qBittorrent, whether NGINX is sending it to the wrong upstream, and whether the response is a 401, 403, redirect, or connection failure.
10.1 NGINX commands
Validate and reload NGINX after edits:
sudo nginx -t
sudo systemctl reload nginxWatch the error log:
sudo tail -f /var/log/nginx/error.logWatch the access log:
sudo tail -f /var/log/nginx/access.logLook for upstream connection failures, requests going to the wrong port, 401 and 403 responses, unexpected redirects, and repeated POST requests to login endpoints.
10.2 qBittorrent-nox systemd logs
If qBittorrent-nox runs as a systemd service, try:
sudo journalctl -u qbittorrent-nox -fIf your service has a different name, list matching units:
systemctl list-units | grep -i qbittorrentThen use the actual unit name. Look for host validation failures, authentication rejections, service-start failures, permission errors, or repeated login attempts from the same proxy IP.
11. Docker-Specific Checks
Docker adds one major source of confusion: 127.0.0.1 inside a container refers to that container, not the host and not another container. If NGINX is in its own container, this upstream is usually wrong:
proxy_pass http://127.0.0.1:8080;That tells the NGINX container to connect to itself on port 8080. Instead, when both containers share a Docker network, use the qBittorrent service or container name:
proxy_pass http://qbittorrent:8080;Confirm that both containers are attached to the same Docker network. In Docker Compose, that usually means both services are listed under the same network or share the default project network.
11.1 Container ports versus host-published ports
Inside a Docker network, NGINX should usually connect to the container port, not the host-published port. If qBittorrent exposes WebUI port 8080 inside the container and maps it as 8090:8080 on the host, another container on the same network normally uses qbittorrent:8080, not localhost:8090.
11.2 Trusted proxy in Docker
The trusted proxy IP should be the address qBittorrent sees as the source of the request. In Docker, that may be the NGINX container IP or the Docker bridge subnet. Prefer the narrowest practical trust rule. Restart both containers after changes:
docker restart nginx qbittorrentUse your actual container names.
12. Cloudflare Or Another Proxy In Front Of NGINX
If Cloudflare, another CDN, a load balancer, or a second reverse proxy sits in front of NGINX, the request path becomes browser to Cloudflare, Cloudflare to NGINX, and NGINX to qBittorrent. NGINX must still pass the public host and protocol that the browser used.
Make sure the qBittorrent WebUI and authentication endpoints are not cached by the upstream proxy. Dynamic authenticated applications should not be served from stale cache.
Real-client-IP handling also becomes more complex. NGINX may receive Cloudflare IPs as direct clients, then pass a forwarded chain to qBittorrent. Configure trusted proxy settings carefully so qBittorrent trusts NGINX, not arbitrary outside clients.
To isolate the problem, you can temporarily set the DNS record to DNS-only if your provider supports that, then test the same NGINX endpoint directly. Keep WebUI authentication and HTTPS in place while testing.
13. Firewall And Authentication Rate-Limit Issues
Repeated failed login attempts can cause temporary rejection or bans depending on qBittorrent settings and version. A reverse proxy can make this harder to read because qBittorrent may see every attempt as coming from the NGINX IP unless forwarded IP handling is configured correctly.
If you have made many attempts, stop automated retries and wait before testing again. Check logs before restarting qBittorrent. Restarting may clear temporary state in some setups, but it can also hide the evidence you need.
Confirm which connecting IP qBittorrent sees. If it sees only the proxy IP, that may be expected, but qBittorrent should trust forwarded headers only from that proxy. If it sees a strange Docker gateway or upstream proxy address, adjust the trusted proxy setting and NGINX headers.

14. Recommended Troubleshooting Order
Use this checklist in order. It avoids chasing browser or Cloudflare problems before proving the basics.
- Test direct local login.
- Test NGINX configuration syntax with
sudo nginx -t. - Verify the upstream address and port in
proxy_pass. - Forward
Host,X-Forwarded-For,X-Real-IP, andX-Forwarded-Proto. - Enable qBittorrent reverse-proxy support if available and trust only NGINX.
- Clear browser cookies and site data for the WebUI domain.
- Check HTTPS behavior and
X-Forwarded-Proto. - Inspect browser developer tools, NGINX logs, and qBittorrent logs.
- Test without a subpath by using a dedicated subdomain.
- Test without an additional proxy such as Cloudflare if one is in front.
15. FAQ
15.1 Why does qBittorrent keep returning to the login page?
A login loop usually means the login POST reaches qBittorrent, but the authenticated session is not accepted afterward. Common causes are a bad Host header, missing X-Forwarded-Proto, stale cookies, CSRF rejection, or untrusted reverse-proxy headers.
15.2 Why does qBittorrent show 401 Unauthorized behind NGINX?
A 401 can mean incorrect credentials, but if the same credentials work locally, the proxied request is probably being rejected because the session, origin, cookie, or forwarded headers do not match what qBittorrent expects.
15.3 How do I fix Invalid Host header in qBittorrent WebUI?
Forward the real public hostname with proxy_set_header Host $host; and configure qBittorrent's equivalent WebUI host validation or reverse-proxy setting to accept the correct domain. Do not hard-code the upstream address as the Host header.
15.4 Should I disable CSRF protection?
No, not as a permanent fix. You may disable it briefly only to confirm a diagnosis in a controlled environment, then re-enable it and fix the proxy headers, scheme, host, or subpath that caused the CSRF failure.
15.5 Does qBittorrent need reverse-proxy support enabled?
If your qBittorrent version provides a reverse-proxy support or trusted proxy option, enabling and configuring it is often necessary for reliable operation behind NGINX. Setting names vary by version, so use the equivalent option in your installation.
15.6 Why does login work by IP but not by domain?
The domain path may introduce HTTPS termination, different cookies, host validation, Cloudflare, or NGINX header changes. If local IP login works, focus on the public Host header, forwarded protocol, cookies, and trusted proxy configuration.
15.7 Can I run qBittorrent WebUI under an NGINX subdirectory?
Yes, but it is more fragile than a subdomain. You must handle trailing slashes, path rewriting, forwarded prefix behavior, cookie paths, and API URLs correctly. A dedicated subdomain is usually simpler.
15.8 Why does qBittorrent login fail only through HTTPS?
NGINX may be terminating HTTPS but failing to tell qBittorrent that the original request was HTTPS. Add proxy_set_header X-Forwarded-Proto $scheme;, use the HTTPS URL consistently, and clear old HTTP cookies.
15.9 What IP should I add as a trusted reverse proxy in Docker?
Add the IP address qBittorrent sees for the NGINX container, or a narrowly scoped Docker network range if your qBittorrent version supports it and you understand the trust boundary. Do not blindly trust all IPs.
15.10 Is it safer to use a subdomain or a URL subpath?
A subdomain is usually simpler and less error-prone. A subpath can work, but it creates more opportunities for login failures involving redirects, CSRF checks, cookies, and API paths.
16. Conclusion
Most qBittorrent WebUI login failures behind NGINX are caused by a small set of reverse-proxy mismatches: the wrong Host header, missing forwarded HTTPS scheme, untrusted proxy addresses, stale browser cookies, CSRF origin mismatches, or subpath rewriting errors. If direct local login works, start with a clean NGINX server block, forward the public host and scheme, configure qBittorrent to trust only the NGINX proxy, then clear browser site data and test again.
Once the WebUI login works, keep authentication, HTTPS, CSRF protection, host-header validation, and clickjacking protections enabled. Troubleshooting should restore a secure reverse-proxy setup, not remove the protections that make remote administration safer.