How to Fix Your SSL Certificate on Your Own Server

You can do this

On your own server the certificate is usually free and usually automatic. When HTTPS is broken it is rarely the certificate itself. Here is the order to work in, and the mixed content problem nobody warns you about.

Order matters more than anything else here: certificate first, then force HTTPS, then HSTS. Never in a different order.

The order, and why it is not negotiable

Three steps. Do them in this sequence and this is a calm afternoon. Do them out of sequence and you can lock visitors out of your own site.

One: get a working certificate covering every hostname you serve.

Two: force HTTPS, so plain HTTP requests redirect.

Three: enable HSTS, so browsers refuse HTTP on return visits.

Why the order is strict: HSTS tells a browser to never use HTTP for your domain again, for as long as the max-age says. If you turn that on while your certificate is broken or missing on some hostname, visitors cannot reach you over HTTPS because it fails, and cannot fall back to HTTP because you told them not to. You have removed both doors. And the browsers that already got the header will keep honouring it until it expires, no matter what you fix on the server.

Getting the certificate

On a typical hosted server this is free and already handled. If you are on cPanel, it is AutoSSL.

cPanel's own documentation says Let's Encrypt is the default AutoSSL provider for all new installations, and that AutoSSL renews certificates expiring within 29 days. Older installs may be running the Sectigo provider instead, so check which one yours uses rather than assuming.

To force a run: cPanel > SSL/TLS Status > Run AutoSSL. That page also shows you which hostnames are covered and which are not, which is usually where the answer is hiding.

If you manage the box yourself, an ACME client renewing from Let's Encrypt is the standard approach. Whatever you use, the thing to verify is that renewal is automatic and actually running. A certificate that expires in ninety days and needs a human is not a solution, it is a scheduled outage.

Why AutoSSL skips a domain

Usually one of these, and the AutoSSL log will normally say which.

  • DNS does not point at this server. Validation checks the hostname resolves to the box asking for the cert. If you moved DNS elsewhere, or the record points at an old IP, validation fails.
  • /.well-known/acme-challenge/ is not reachable. This is the big one, and it is self inflicted more often than not. A redirect rule, a blanket deny on dot-directories, or an over-eager firewall rule on /.well-known/ breaks validation. Never blanket-deny or blanket-redirect that path.
  • The hostname is not on the server. A subdomain in DNS that has no vhost cannot be validated. Either add it properly or remove it from the request.
  • Rate limits. If you have been retrying, you may simply be waiting. Read the log rather than clicking Run AutoSSL again.

Force HTTPS, once the certificate works

A certificate that exists but is not used protects nobody. Redirect plain HTTP to HTTPS at the server, not in application code, so it covers static files too.

nginx:

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

Apache, in the HTTP vhost:

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

Leave /.well-known/acme-challenge/ reachable over HTTP if your ACME client uses the HTTP-01 challenge. A blanket redirect can break renewal, and you will not notice until the certificate expires.

Mixed content, the part that catches everyone

Your certificate is valid, HTTPS is forced, and the browser still will not show the padlock. That is mixed content: your HTTPS page is pulling images, scripts, stylesheets or fonts over plain http://.

The cause is almost always http:// URLs hardcoded somewhere, in page content, in configuration, in theme settings. Browsers block insecure scripts outright, so it is not only cosmetic. A blocked script means a broken feature.

Open the browser console on the failing page. It names every offending URL. Fix them at the source rather than papering over them.

One thing not to do: protocol-relative URLs like //example.com/thing.js are a legacy pattern from when sites straddled HTTP and HTTPS. They are no longer recommended. Write https:// and be explicit.

Then, and only then, HSTS

With the certificate valid and HTTPS forced everywhere, HSTS is the finishing move. Start short.

Start here, while you confirm nothing is broken:

  nginx:   add_header Strict-Transport-Security "max-age=300" always;
  Apache:  Header always set Strict-Transport-Security "max-age=300"

Then, once you are confident:

  nginx:   add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
  Apache:  Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"

max-age=300 means a mistake costs you five minutes instead of a year. Note the nginx always parameter and the Apache always keyword, which extend the header to error pages.

About preload

You will see advice to submit your domain to the HSTS preload list. Think hard first.

hstspreload.org requires max-age of at least 31536000, plus includeSubDomains, plus the preload token, plus a valid certificate, plus an HTTP to HTTPS redirect on the same host, plus every subdomain reachable over HTTPS. That last requirement is the one that hurts, because it includes the internal tool on a subdomain that you forgot exists.

Their own wording is that inclusion "cannot easily be undone" and that removal "takes months to reach users with a Chrome update". This is baked into browsers. Getting off the list is not a config change, it is a waiting game measured in browser release cycles.

A one year max-age with includeSubDomains and no preload gives you nearly all the protection and keeps a door open. That is what we would ship. The HSTS glossary entry goes into it further, and the rest of the headers are covered in our Apache and nginx security headers guide.

Check your work in seconds

Run your site through our free safety check to confirm the fix is live, and see what else a shopper would notice.

Run a free check

Frequently asked questions

Why is my site still not secure when the certificate is valid?

Mixed content, nearly always. Your HTTPS page is loading something over plain http://, usually an image, script or stylesheet with a hardcoded URL. The browser console lists every offending URL on the page. Insecure scripts are blocked outright, so this can break features and not just the padlock.

How do I force AutoSSL to run on cPanel?

Go to cPanel > SSL/TLS Status and choose Run AutoSSL. That page also shows which hostnames are covered. AutoSSL renews certificates expiring within 29 days on its own, so a manual run is mostly for diagnosing a domain it is skipping.

Which certificate authority does cPanel AutoSSL use?

cPanel documents Let's Encrypt as the default AutoSSL provider for all new installations. Older installs may be configured with the Sectigo provider instead, so check your own server rather than assuming. It matters if you publish CAA records, since those restrict which authorities may issue for your domain.

Why does AutoSSL keep skipping one of my subdomains?

The usual causes are DNS not pointing at the server, no vhost for that hostname, or /.well-known/acme-challenge/ being unreachable because of a redirect or deny rule. That last one is common on hardened servers. Never blanket-deny or blanket-redirect /.well-known/, because that is exactly where certificate validation happens.

Can I use protocol-relative URLs like //example.com to fix mixed content?

You can, but do not. Protocol-relative URLs are a legacy pattern from when sites served both HTTP and HTTPS, and they are no longer recommended. Write https:// explicitly. It is clearer and it does what you mean.

Should I enable HSTS as soon as I have a certificate?

Not immediately. Get the certificate working on every hostname, force HTTPS, confirm there is no mixed content, and only then add HSTS. Start at max-age=300 so a mistake costs five minutes. HSTS tells browsers to refuse HTTP for your domain, and they honour that until it expires regardless of what you fix afterwards.

SSL certificate on other platforms

Other fixes for A custom site

See the full fix-it matrix →

Prove your site is safe.

Once it is fixed, show it. Get a badge your shoppers can verify, backed by continuous checks. Free to start.

Get started free Run a free check