How to redirect http:// to https://
If your site answers on http:// without sending the visitor to
https://, you have two problems and only one of them is about ranking. The
ranking one is old news. The other is that a browser now writes "Not secure" next to your
address, and the person reading it has no idea whether that means you are careless or
compromised.
We found this on our own site. Docket audited docketseo.app, returned
http:// does not redirect to https:// at HIGH, and it was right — the plain
HTTP address answered normally with no redirect at all. A tool that ships this check was
shipping the fault. That is embarrassing in a useful way, because fixing it turned up the part
of this problem nobody writes down.
First, confirm it rather than assume it
Type your domain into a browser and you will almost certainly end up on HTTPS, because the browser upgraded it for you. That tells you nothing about what your server does. Ask the server directly:
curl -sI http://yourdomain.com/ | head -1
You want a 301 and a Location: header pointing at the
https:// version of the same path. If you get 200 OK, your server is
happily serving the insecure version to anyone who asks for it — including any crawler that
does not upgrade, and any visitor following an old link.
The fix, by where the site is hosted
On most managed hosts this is one setting, and the setting is usually already there:
- GitHub Pages — Settings → Pages → Enforce HTTPS.
- Netlify, Vercel, Cloudflare Pages — on by default; look for "Force HTTPS" or "Always Use HTTPS" if it is not.
- Cloudflare in front of your own server — SSL/TLS → Edge Certificates → Always Use HTTPS. Set the encryption mode to Full (strict), not Flexible; Flexible re-encrypts to your origin over plain HTTP and quietly reintroduces the problem you are fixing.
- Nginx — a server block on port 80 whose only job is
return 301 https://$host$request_uri;. Return the redirect, do not rewrite: a rewrite can drop the path and land everyone on the homepage. - Apache —
Redirect permanent / https://yourdomain.com/in the port-80 virtual host, or the mod_rewrite equivalent if you already use it.
Two details that cost people a morning. Use 301, not 302 — a temporary
redirect tells a search engine to keep the old URL. And preserve the path: a redirect that
sends /pricing to the homepage loses every deep link you have ever earned, which
is a worse outcome than the problem.
When the setting refuses — the part nobody documents
This is what actually happened to us. The API refused:
PUT /repos/OWNER/REPO/pages https_enforced=true
404 — "The certificate has not finished being issued"
HTTPS itself was working. A valid certificate was being served, every page loaded over TLS,
nothing looked broken. What was stuck was the certificate state: GitHub reported
dns_changed, and it will not let you enforce HTTPS while it is re-validating.
The cause was one DNS record we had stopped thinking about. The apex domain was configured
correctly — the right A records, the right CNAME file in the repository. The
www subdomain was not: it still pointed at the registrar's parking service from
before the site existed. A host that issues a certificate covering both the apex and
www cannot finish validating while half of that pair answers to somebody else.
So the check that unblocks the tick box is not on the page you are looking at:
dig +short yourdomain.com A
dig +short www.yourdomain.com CNAME
The apex should return your host's addresses. The www record should point at
your host too — not at a registrar landing page, not at an old server, and not at nothing.
Fix that, and the certificate finishes issuing on its own; the setting then takes normally.
HSTS is the follow-up, and it is not the same thing
A redirect fixes the request after it happens. Strict-Transport-Security stops
the insecure request being made at all: once a browser has seen the header, it goes straight to
HTTPS for that domain without asking. Add it after the redirect works, never before — the
header tells browsers to refuse plain HTTP for your domain for its whole
max-age, and if HTTPS is broken when they act on that, they cannot fall back.
Start with a short max-age, confirm nothing broke, then raise it. Treat
preload as close to irreversible: removal from the browser preload lists takes
months.
What Docket does about it
It probes the plain-HTTP address directly rather than trusting the browser's upgrade, so it sees what a crawler sees. It reports the missing redirect and the missing HSTS header as separate findings, because they are separate jobs and doing the second one first is how sites break. Both name the change to make.
It found this on the site that sells it. That is the argument for running an audit against your own work rather than reading about one.
Common questions
Does a missing HTTPS redirect actually affect ranking?
HTTPS has been a Google ranking signal since 2014, but the redirect matters more for duplication and trust than for the signal itself: without it the same page is reachable at two addresses, and browsers label the insecure one 'Not secure' in the address bar.
Should I use a 301 or a 302?
301. A 302 is a temporary redirect and tells a search engine to keep indexing the http:// URL, which is the opposite of what you want.
Why does 'Enforce HTTPS' refuse to turn on?
Usually because the certificate has not finished being issued. On GitHub Pages the API reports a certificate state such as dns_changed. The common cause is a DNS record that does not point at the host — often a www subdomain still pointing at a registrar parking page — because the certificate covers both the apex and www.
Should I add HSTS at the same time?
No. Get the redirect working first. HSTS tells browsers to refuse plain HTTP for your domain for the whole max-age, so if HTTPS is broken when they act on it there is no fallback. Add it afterwards with a short max-age and raise it once you are confident.