Discussing software, the web, politics, sexuality and the unending supply of human stupidity.

How to nuke Chrome's HSTS database (if you really need to)

When debugging hairball web dev problems, occasionally you’ll end up sending HSTS headers to yourself while on localhost. These are surprisingly tricky to remove from Google Chrome. Quite sensibly, the Chrome developers store HSTS hosts hashed.

The standard answer you read online is to go to chrome://net-internals/#hsts. You can check to see if there’s an entry in Chrome’s HSTS database, and you can remove it. But I sit there and type every version of localhost, localhost:3000,,, ::1 and so on that I can think of and yet the problem remains. (The query form works whether you prefix the query with and without the https scheme and :// separator. So and will both search for the same entry. The query form is quite useful if you need to debug your own site’s HTTPS/HSTS setup, so I recommend it.)

The unfortunate result of having screwed up your localhost HSTS entry in Chrome is you then spend the next few days having to use some other browser you aren’t familiar with to work on localhost. This isn’t ideal.

A rather brute force solution to a polluted HSTS database is to delete the database completely. It isn’t a great solution, but if you’ve polluted the database such that you can’t remove localhost from it despite numerous attempts, sometimes needs must. So here’s how you do it.

  1. Close Chrome. It caches the HSTS database in memory, so if you just remove the file, it’ll get rewritten.
  2. Find where Chrome stores the database. On Mac OS X, using the Chrome that’s in use as of today (August 2, 2016), this is in ~/Library/Application Support/Google/Chrome/Default/ in a file called TransportSecurity. Older versions of Chrome store it in a file called StrictTransportSecurity. If you are using Chrome Canary, substitute “Chrome” for “Chrome Canary” in the paths. If you are using Chromium, substitute “Chromium” for “Google/Chrome”. On Linux, check out .config/google-chrome/Default/ or .config/chromium/Default as appropriate. On Windows, ask Cthulhu.
  3. Replace the TransportSecurity file with an empty JSON object: {}. On OS X, echo "{}" > ~/Library/Application\ Support/Google/Chrome/Default/TransportSecurity
  4. Restart Chrome.

Now, be aware that resetting your HSTS database /does/ undermine the security benefits of having HSTS in your browser. After doing it, you should keep an eye out for spoofing, MITM attacks, phishing attempts and so on until Chrome picks up replacement HSTS headers from the sites you visit frequently. This /is/ pretty much the last resort and you shouldn’t be doing it routinely. Don’t do it unless you absolutely have to. If you are going to run an app on localhost that might try and force HTTPS, do the testing in an Incognito window or in a browser whose profiles/cache you can fully nuke after you are done.

Incidentally, I haven’t had any similar issue in Firefox because Firefox’s HSTS database is tied into the browser history, meaning that you simply find an entry in history and tell Firefox to forget about the site, and it removes the HSTS entry.