Skip to content

Force HTTPS

Every site CorePanel serves answers on both port 80 and port 443. Unless HTTP redirects to HTTPS, a visitor who types the bare domain, an old bookmark, or a link from an email signature keeps browsing over an unencrypted connection — and so does every form they submit.

The Force HTTPS setting makes plain HTTP answer a permanent redirect to the same URL over HTTPS. It is set per domain and per subdomain, and it is on by default for new domains.

A request that arrives over HTTP gets:

HTTP/1.1 308 Permanent Redirect
Location: https://www.example.com/checkout?step=2

The redirect preserves the scheme change only — path, query string and hostname stay as they are. The status code is 308, not 301, and that difference matters: a 301 allows the browser to turn a POST into a GET, which silently drops the body of a form submitted over HTTP. 308 keeps the method and the body intact. Both are cached by browsers the same way.

Requests under /.well-known/ are never redirected, so ACME certificate challenges keep working over HTTP.

It only applies when there is a certificate

Section titled “It only applies when there is a certificate”

This is the part worth internalising, because it is what makes the setting safe:

The redirect is evaluated per request, and only fires while that exact hostname has a currently valid certificate.

Three consequences follow:

  • Turning it on before a certificate exists is harmless. The setting lies dormant and the site keeps serving over HTTP. As soon as the certificate is issued, the redirect starts working on its own — you do not have to come back and enable it.
  • A failed renewal degrades to HTTP instead of taking the site down. Without this rule, an expired certificate plus a forced redirect is a site that answers “redirect to a URL the browser refuses to load” — an outage with no way back in through the browser.
  • An expired certificate counts as no certificate. The check is validity, not presence of a file on disk.

Certificates come from the wildcard CorePanel issues for the domain (*.example.com + example.com), or from the per-hostname certificate obtained on the first HTTPS request. See SSL Certificates for how and when each is issued.

In the account workspace, open the Domains or Subdomains table and click the edit button on the row. The dialog has an HTTPS section with the switch. Rows that redirect show a shield next to their name.

The change is applied on the next configuration reload, with no downtime and no dropped connections.

How the domain was createdForce HTTPS
Added from the panel or the CLIOn
Created with a new accountOn
Existing domain, upgraded to a version with this featureOff
Imported from cPanelOff
Restored from a backupOff

A brand-new domain has no traffic yet to break: no payment provider is calling an http:// webhook on it, and no application has an http:// canonical URL stored in its database. Turning the redirect on is what an operator would do by hand anyway.

A migrated site is the opposite case. It is live somewhere else right now, with integrations registered against http:// URLs at providers nobody is about to reconfigure. Flipping a whole imported server to HTTPS-only on day one is how a migration goes wrong at scale, so imports and restores leave it off and you enable it per domain once the site is verified.

Upgrades leave existing domains alone for the same reason: changing how a live site answers is an operator decision, not a side effect of installing a package.

If WordPress still has an http:// site URL, turning the redirect on creates a loop: the server sends the browser to https://, WordPress sends it back to its http:// canonical, and the two bounce off each other until the browser gives up.

The panel checks for this before saving. When it finds a WordPress instance on the domain with an http:// site URL, it warns and offers to update the site URL in the same step — and if that update fails, it leaves the redirect off rather than saving a configuration it knows will loop.

The same trap exists for any application that stores its own absolute base URL (Nextcloud, Matomo, a hardcoded APP_URL in a .env). Those the panel cannot see; check them before enabling.

Terminal window
# Should answer 308 with an https:// Location
curl -sI http://example.com/some/path?a=b | head -3
# Should NOT redirect — ACME challenges stay on HTTP
curl -sI http://example.com/.well-known/acme-challenge/test | head -1
# What certificate the hostname actually presents
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -subject -dates

If the first command returns 200 instead of 308, the hostname has no valid certificate yet — check the third command before looking anywhere else.