Fixing Safari's 'can't establish a secure connection' when updating a self-signed certificate

I do a lot of local development, and since almost everything web-related is supposed to use SSL these days, and since I like to make local match production as closely as possible, I generate a lot of self-signed certificates using OpenSSL (usually using Ansible's openssl_* modules).

This presents a problem, though, since I use Safari. Every time I rebuild an environment using my automation, and generate a new certificate for a domain that's protected with HSTS, I end up getting this fun error page:

Safari Can't Open the Page - Safari can't open the page because Safari can't establish a secure connection to the server servername.

Safari Can't Open the Page – Safari can't open the page because Safari can't establish a secure connection to the server 'servername'.

There's no possible way of adding an exception, or deleting the old cert from Keychain Access, or really any way to get around this—at least none exposed via Safari's UI.

There are only three ways to get around this annoying issue—one is good for one-off use cases, one requires the deletion of the HSTS cache, the other requires wiping all your web history:

Method 1 - Private browsing session

  1. Open a new Private Browsing window (Shift + ⌘ + N)
  2. You should see the link to add an exception for the site.

Note that this exception only persists during that private browsing session. This definitely works in a pinch, or when you're doing a bunch of HTTPS testing.

Method 2 - Clear HSTS cache

This is the easiest method which doesn't require to to re-login to every single site and service you use but allows more permanent exceptions to be stored. Basically:

  1. killall nsurlstoraged to stop the HTTP storage manager (since it has an in-memory cache of the HSTS hosts).
  2. rm -f ~/Library/Cookies/HSTS.plist to delete the HSTS cache file.
  3. launchctl start /System/Library/LaunchAgents/com.apple.nsurlstoraged.plist to start up nsurlstoraged again.

I'd rather have the ability to drop just one domain, but it's really annoying trying to edit plist files (it basically has to be done in Xcode nowadays).

Method 3 - Clear all browsing history

This method will log you out of all websites and sessions in Safari, and also wipe out local storage, etc. Not a horrible thing to do every now and then, but it can be really annoying if you do it a few times a day!

  1. Go to Safari > Clear History... > all history.

There's apparently also a way to force the cert by copying it into Keychain Access manually, then trusting it via Terminal command, but that's super annoying for projects where I rebuild them sometimes dozens of times a day.

The self-signed certs you add exceptions for are also added to Keychain Access, but deleting them from there and restarting Safari doesn't do the trick.

After using one of the methods above, I am able to see the options to add an exception by clicking the 'visit the website' link:

Safari HTTPS Certificate exception - This Connection is not Private

Comments

I like to use a wildcard cert `*.test` for local work. Each site needs to be approved but the setup is once.

Thank you for this information I was really stumped as to what was going on in the first place. I came up with a way to use PlistBuddy (part of macOS) quite easily to remove a single domain from the HSTS plist.

HSTS_DOMAIN=example.com
killall nsurlstoraged
/usr/libexec/PlistBuddy -c "Delete :com.apple.CFNetwork.defaultStorageSession:${HSTS_DOMAIN}" ~/Library/Cookies/HSTS.plist
defaults read ~/Library/Cookies/HSTS.plist
launchctl start /System/Library/LaunchAgents/com.apple.nsurlstoraged.plist

This page is the only useful one on the internet to solve that problem.

This isn't working for me in the latest macOS release & Safari versions, I get this error:

$ /usr/libexec/PlistBuddy -c "Delete :com.apple.CFNetwork.defaultStorageSession:${HSTS_DOMAIN}" ~/Library/Cookies/HSTS.plist
Error Reading File: /Users/dmckenna/Library/Cookies/HSTS.plist

I tried opening the file with XCode but it gives an error saying I can't read the file and says I should change the permissions in Finder. I check Finder and the permissions are fine, it even loads a preview of the file.

So, let me merge all the above here, if you are looking in 2020+ final steps are:

1. Allow terminal to edit files and folders (http://osxdaily.com/2018/10/09/fix-operation-not-permitted-terminal-err…)
2. Open terminal and execute line by line:
HSTS_DOMAIN=example.com
killall nsurlstoraged
/usr/libexec/PlistBuddy -c "Delete :com.apple.CFNetwork.defaultStorageSession:${HSTS_DOMAIN}" ~/Library/Cookies/HSTS.plist
defaults read ~/Library/Cookies/HSTS.plist
launchctl start /System/Library/LaunchAgents/com.apple.nsurlstoraged.plist

Thanks for this. I had to use the Finder to browse directly to ~/Library/Cookies/ and manually delete the HSTS.plist file. That worked. The rm command in terminal returned that the operation was not allowed.
Cheers!

Wow, this helped me big time!

I had visited a site (the management console of a media recorder) when it wasn't properly responding to requests. Safari "somehow" was caching the Error Response in a way that wasn't responding to clearing the cache or any website data. But the URL would work under private browsing, so it was clearly some other information Safari had saved about the page.

It turns out it was in the HSTS cache. Instead of wiping it out entirely, I:

1) Opened ~/Library/Cookies/HSTS.plist in PLIST editor; searched for the misbehaving hostname, and deleted its entry
2) sudo killall nsurlstoraged
3) Save HSTS.plist
4) launchctl start /System/Library/LaunchAgents/com.apple.nsurlstoraged.plist

And on next visit, it loaded correctly. Huzzah! This has been plagueing me for over 2 weeks now...

For anyone here on Safari 14+:

1. Open Safari preferences
2. Privacy -> Manage Website Data...
3. Search for localhost and delete the entry

No need to leave Safari!

Just to update this article for anybody coming from Google in 2024:

The HSTS file is now at:

/System/Volumes/Data/Users/username/Library/Containers/com.apple.Safari/Data/Library/Caches/WebKit/HSTS/HSTS.plist

You will not find them in ~/Library/HSTS.plist any more.

Hope this helps somebody!