# Fix 301 redirect loop (Certbot duplicate 443 block) ## Cause Certbot added a **second** HTTPS server block that only has: - `location / { return 301 https://$host$request_uri; }` - `listen 443 ssl` + SSL cert paths That block is matched first for `https://testforapp.website/`, so every request gets 301 → same URL → loop. Your real HTTPS block (frontend, API, phpMyAdmin) is never used for `/`. ## Fix on VPS 1. **Open the site config** ```bash sudo nano /etc/nginx/sites-enabled/testforapp.website ``` 2. **Find and remove the Certbot-only HTTPS block** Look for a block that looks like this (it may be at the **top** of the file, before the `map` and your big HTTPS server): ```nginx server { server_name testforapp.website; location /.well-known/acme-challenge/ { root /var/www/certbot; } location / { return 301 https://$host$request_uri; } listen [::]:443 ssl ipv6only=on; # managed by Certbot listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/testforapp.website/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/testforapp.website/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot } ``` **Delete this entire `server { ... }` block** (from `server {` through the closing `}`). 3. **Ensure your main HTTPS block has SSL and listen** Find your main HTTPS server (the one with `# HTTPS server`, `root /opt/app/frontend/dist`, all the `location` blocks). It must have at the top of that block (right after `server {`): - `listen 443 ssl;` and `listen [::]:443 ssl;` - `ssl_certificate` and `ssl_certificate_key` (and optionally `include /etc/letsencrypt/options-ssl-nginx.conf;` and `ssl_dhparam`) If those lines are missing, add them (copy from the block you deleted): ```nginx server { listen 443 ssl; listen [::]:443 ssl; server_name testforapp.website; ssl_certificate /etc/letsencrypt/live/testforapp.website/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/testforapp.website/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # ... rest of your config (root, locations, etc.) } ``` 4. **Test and reload** ```bash sudo nginx -t && sudo systemctl reload nginx ``` 5. **Verify** ```bash curl -I -k https://127.0.0.1/ -H "Host: testforapp.website" ``` You should see `200 OK` (or `304`) and no `Location` header, and https://testforapp.website/ should load in the browser.