Chrome loads my local hosted website as https instead of http resulting an error (started happening after an ubuntu update)

Solution 1:

If you navigate to the article posted in the superuser post, the tl;dr explains it:

tl;dr: Chrome 63 (out since December 2017), will force all domains ending on .dev (and .foo) to be redirected to HTTPS via a preloaded HTTP Strict Transport Security (HSTS) header.

So your only solutions are to either change to something other than the .dev TLD, or create a certificate and implement HTTPS in your virtual host configuration for local development.


In order to explain why that's your only solution, I'll need to start with what HSTS means and how it works.

HSTS in General

HSTS is a relatively new HTTP header, which when set, tells browsers that the next time someone navigates to the domain, only access it using HTTPS without the need for any server-side redirection.

For example, let's consider that you navigated to http://example.com. In the response headers, you receive the following:

Strict-Transport-Security: max-age=31536000

This header tells the browser that, for the next year (31536000 seconds), when the user accesses http://example.com, redirect that URL to https://example.com locally without the need of any server redirects. And only then, access the site with https://example.com.

HSTS for subdomains

The previous is only valid for a single domain. So for example, if you try to access http://subdomain.example.com, the site would work without any redirects.

To solve this, the previous header should be changed to:

 Strict-Transport-Security: max-age=31536000; includeSubdomains

Now, even if you never accessed any subdomains of example.com, the browser will ALWAYS redirect subdomains to https before making a request.

HSTS preloading

The final step is to fix one last issue. The first time you ever access a site, you would still be accessing it using HTTP, which would redirect you to HTTPS and send you the HSTS header. This isn't secure and is still a security issue.

To solve this, major browsers use Chrome's HTTP Strict Transport Security (HSTS) preload list to hardcode domains that can only be accessed with HTTPS. You can find the submission form here: https://hstspreload.org/

The only modification you need to do before submitting your domain is to modify your header so it caches in browsers for at least 2 years, and add the preload option to it.

Strict-Transport-Security: max-age=63072000; includeSubdomains; preload

After you submit your domain, and once a new version of Chrome is released (or any other browser implementing Chrome's HSTS preload list, and not necessarily the next version), your domain will be hardcoded into Chrome as HTTPS-only.

HSTS preloading for TLDs

Owners of a TLD are allowed (and encouraged) to submit their whole TLD for HSTS preloading.

Owners of gTLDs, ccTLDs, or any other public suffix domains are welcome to preload HSTS across all their registerable domains. This ensures robust security for the whole TLD and is much simpler than preloading each individual domain.

And since Google owns the .dev TLD, they did just that. So now all *.dev domains will only work in HTTPS under Chrome. And since most browsers use the same preload list, those browsers will stop working as well.


If you search the list of preloaded domains (CAUTION: The page is over 40MB and will take a while to render. So your computer might freeze if it isn't powerful enough!), you can find that the TLDs are preloaded: google, dev, foo, page, app, chrome.

// eTLDs
// At the moment, this only includes Google-owned gTLDs,
// but other gTLDs and eTLDs are welcome to preload if they are interested.
{ "name": "google", "policy": "public-suffix", "mode": "force-https", "include_subdomains": true, "pins": "google" },
{ "name": "dev", "policy": "public-suffix", "mode": "force-https", "include_subdomains": true },
{ "name": "foo", "policy": "public-suffix", "mode": "force-https", "include_subdomains": true },
{ "name": "page", "policy": "public-suffix", "mode": "force-https", "include_subdomains": true },
{ "name": "app", "policy": "public-suffix", "mode": "force-https", "include_subdomains": true },
{ "name": "chrome", "policy": "public-suffix", "mode": "force-https", "include_subdomains": true },