How do I redirect HTTP to HTTPS for my whole site?
An HTTP to HTTPS redirect sends a visitor who requests the plaintext version of a URL to the encrypted version instead. MDN's guide to HTTP redirections describes the 301 status code as the permanent redirect, and the practical fix is to answer every request on port 80 with a 301 whose Location header points at the https URL. Redirecting the whole host, not a single path, matters because browsers and crawlers still open http links that were shared or indexed long ago.
Why this matters
A 301 moved permanently tells clients and search engines that the address has changed for good, so they update their bookmarks and their index. A 302 found is a temporary redirect and does not transfer that trust, so crawlers keep the plaintext URL and re-check it. For a site-wide HTTPS migration you want the 301, sent for every hostname you serve, including the www and apex names. Confirm that the destination itself is already served over HTTPS with a valid certificate, otherwise the redirect simply moves the failure one hop down the chain.
How to fix it
On Nginx the return directive takes a status code and a URL; inside a server block that listens on port 80 it preserves the requested path while rewriting the scheme. Apache's mod_rewrite module exposes the RewriteRule directive with an R flag that sets the external redirect status, and RewriteCond can test the HTTPS variable to skip requests that are already secure. Express exposes res.redirect with an explicit status code, and checking the forwarded protocol keeps a reverse proxy from causing a loop.
# Nginx
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
# Apache
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
// Express
app.use((req, res, next) => {
if (req.secure || req.headers['x-forwarded-proto'] === 'https') return next();
return res.redirect(301, 'https://' + req.headers.host + req.originalUrl);
});
If a CDN such as Cloudflare already offers Always Use HTTPS, enabling it redirects every http request to https for all subdomains and hosts, on every plan. Cloudflare advises against also redirecting at the origin, because two redirect layers can produce a loop. Whichever layer owns the HTTP to HTTPS redirect, keep the rule in one place so the two layers cannot disagree. Pick one layer to own the redirect and confirm the final response arrives with a single 301 and no loop. After the redirect is stable, add a Strict-Transport-Security header so returning visitors skip the plaintext request altogether.
How to verify the fix
Request the plaintext URL and read the status line and the Location header; the first response should be a 301 pointing at the https address, followed by a 200 on the secure page. Confirm that the chain contains a single redirect and that no request bounces between the two schemes, and fix any link in your own HTML that still points at the plaintext address, because an internal http link forces an extra hop for every visitor.
curl -sI http://example.com/ | grep -i -E 'HTTP/|location'
Automated check
When the Auditor cannot reach your site over HTTPS it raises a Not using HTTPS finding at High severity. A redirect is often the fastest way to clear it, because the encrypted endpoint usually already exists; pair it with Strict-Transport-Security so the plaintext request disappears for repeat visitors.
Scan your app free →