All guides · Security

Redirecting HTTP to HTTPS

Having HTTPS is only half the job. Visitors still reach the http:// version of your site: when they type example.com without a scheme, follow an old link or open an old bookmark. If that version serves the page instead of redirecting, those visitors stay on an unencrypted connection.

Why it matters

A page served over HTTP has none of the protection HTTPS gives: anyone on the network path can read or change it, including any links or forms that would have taken the visitor to the secure site.

A permanent redirect from every http:// URL to its https:// equivalent fixes that for each visit, and tells search engines that the HTTPS URLs are the ones to index. It also avoids having two copies of every page.

A redirect alone still leaves the very first request on plain HTTP. HSTS closes that gap for returning visitors, and it requires the redirect to be in place first.

What we check

We request the http:// version of the scanned page and follow up to two redirects.

Result When
Pass the request ends on an https:// URL, or a redirect points to https://
Fail the http:// URL serves a response without redirecting to HTTPS
Info nothing accepts connections on port 80, so nothing is served over HTTP
Couldn’t test the request failed for another reason, such as a timeout

The “info” case is fine from a security point of view, but visitors who type your domain without https:// may get a connection error in browsers that try HTTP first. A redirect gives them a working page.

How to fix

Redirect every HTTP request to the same host and path on HTTPS with a 301 (permanent) status. 308 also works and keeps the request method for non-GET requests.

Nginx

server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
}

$request_uri keeps the path and query string, so http://example.com/a?b=1 goes to https://example.com/a?b=1.

Apache (in the port 80 virtual host or .htaccess)

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

Or, in a dedicated <VirtualHost *:80>:

Redirect permanent / https://example.com/

Cloudflare: SSL/TLS → Edge Certificates → Always Use HTTPS → On. Cloudflare then redirects at the edge before the request reaches your server.

Behind a load balancer or proxy that terminates TLS, your application sees every request as HTTP. Redirect at the proxy, or have the app check the X-Forwarded-Proto header from your trusted proxy instead of the connection scheme. Otherwise HTTPS requests get redirected to HTTPS again in a loop.

Things to watch

  • Use a permanent redirect. 302 and 307 are temporary; browsers and search engines keep coming back to the HTTP URL.
  • Keep the path. Sending every HTTP URL to the HTTPS home page breaks deep links.
  • Redirect to the same host first if you plan to preload HSTS: http://example.com → https://example.com, then any www/non-www redirect.
  • Do not serve content on port 80 for any other purpose, except ACME HTTP-01 challenges (/.well-known/acme-challenge/) if your certificate client needs them. Most clients handle those before the redirect applies.

MDN’s guide to redirections in HTTP explains the redirect status codes and how browsers treat each one.

Last updated October 24, 2026