12

/usr/bin/python3 from Xcode/CLT on macOS 10.15 (DB6/PB5 at the moment, with Xcode 11 beta 6) fails with SSL: CERTIFICATE_VERIFY_FAILED for all HTTPS requests originating from PSL, e.g. from urllib.request:

$ /usr/bin/python3 -c 'import urllib.request; urllib.request.urlopen("https://www.apple.com/")'
...
urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1056)>

How to solve this problem?

(I know the answer, will post shortly; just sharing it in case other people run into it.)

4ae1e1
  • 7,228
  • 8
  • 44
  • 77
  • Btw https://stackoverflow.com/questions/44261444/ssl-certificate-verify-failed-error-on-mac is somewhat related, but that's a third party installation (from god knows what channel), whereas this is about the official distribution provided by Apple. – 4ae1e1 Aug 23 '19 at 16:52
  • I think that question is talking about installer provided by PSF. – Franklin Yu Feb 21 '20 at 08:44

7 Answers7

27

Supplemental to @4ae1e1's answer, you can create a symlink to the SSL folder instead of rsyncing it. This will give the added benefit of keeping any changes in /etc/ssl up-to-date at /Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.7/etc/ssl/.

/usr/bin/sudo /bin/mkdir /Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.7/etc
/usr/bin/sudo /bin/ln -s /etc/ssl/ /Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.7/etc/

Should do it.

Jiangge Zhang
  • 4,298
  • 4
  • 25
  • 33
bheinz
  • 1,230
  • 1
  • 10
  • 11
  • 2
    Use `-p` with `mkdir`if it says "No such file or directory". – Dmytro Bogatov Mar 05 '20 at 05:30
  • In my case, `xcode-select -p` shows `/Library/Developer/CommandLineTools` so I thought to try `sudo mkdir /Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/Current/etc` and `sudo ln -s /etc/ssl/ /Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/Current/etc/` but as @4ae1e1 says below, that's irrelevant because `python3 -c 'import ssl; print(ssl.get_default_verify_paths())'` doesn't care – yuzisee Apr 16 '22 at 13:55
  • What worked for me: `sudo mkdir -p /Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.7/etc` and `sudo ln -s /etc/ssl/ /Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.7/etc/` then I needed an extra `sudo xcode-select -s /Library/Developer/CommandLineTools/` – yuzisee Apr 16 '22 at 14:04
11

The problem is that /usr/bin/python3 (from either Xcode or CLT) fails to correctly locate the trust store in /etc/ssl, as we can see using ssl.get_default_verify_paths():

$ /usr/bin/python3 -c 'import ssl; print(ssl.get_default_verify_paths())'
DefaultVerifyPaths(cafile=None, capath=None, openssl_cafile_env='SSL_CERT_FILE', openssl_cafile='/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.7/etc/ssl/cert.pem', openssl_capath_env='SSL_CERT_DIR', openssl_capath='/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.7/etc/ssl/certs')

It's looking into /Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.7/etc/ssl, which doesn't exist.

Knowing this, we can use the following hack:

$ sudo rsync -avzP /etc/ssl/ /Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.7/etc/ssl/

I've submitted a bug report to Apple (btw, just realized bugreport.apple.com is now gone, and I had to use the Feedback Assistant website). Open radar https://openradar.appspot.com/7111585 (that radar number is unfortunately wrong — since bugreport.apple.com is gone, I don't have a radar number anymore, only a feedback number FB7111585).

4ae1e1
  • 7,228
  • 8
  • 44
  • 77
  • 2
    Before executing the `rsync` hack, I faced error saying `/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.7/etc/ssl/` does not exist. At the end, I ran `/usr/bin/sudo /bin/mkdir /Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.7/etc` to create the `etc` directory (provided by @bheinz answer) before doing `rsync`, finally it worked. – wltheng Feb 02 '20 at 02:52
  • Update: now they thought they fixed the issue, but they didn’t. Now `cafile` points to `Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.7/etc/ssl/cert.pem` but the entire `etc` folder doesn’t exist under the 3.7 folder, so they still fail to resolve the correct certificate. – Franklin Yu Feb 21 '20 at 08:20
  • 1
    Update: Apple’s attitude is “use Requests instead”. – Franklin Yu Feb 21 '20 at 08:43
2

According to this GitHub issue, Apple refused to fix this:

The problem behaves as intended.

certifi is a third-party module, not part of Python itself.

urllib is a low-level library. It can handle SSL, but you must explicitly set up the SSL context with a cafile.

Try the following instead:

pip3 install requests
python3 -c 'import requests; print(requests.get("https://apple.com").text)'

If you only want to get cacert.pem, you can use pip3 install certifi, but you must still explicitly pass cafile to urllib.

So my solution is simply using Requests instead. This is supported and future proof.

Franklin Yu
  • 8,920
  • 6
  • 43
  • 57
2

You should reinstall Xcode command line tools that contains Python.

pip3 uninstall -y -r <(pip requests certifi)
brew uninstall --ignore-dependencies python3

sudo rm -rf /Library/Developer/CommandLineTools
xcode-select --install
sudo xcode-select -r

python3 -m pip install --user certifi
python3 -m pip install --user requests
Victor Kushnerov
  • 3,706
  • 27
  • 56
0

If, like me, you ended up here because you were having this problem with a python installation that was done through homebrew using pyenv, then here's what I had to do to fix this thing.

Specifically, I had the issue because I had previously tried to install python 3.6 on an m1 mac using these instructions: Install python 3.6.* on Mac M1

  1. Uninstall the x86 version of homebrew if you have it:
arch -x86 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/uninstall.sh)"
  1. Save your homebrew configuration using brew bundle
  2. Uninstall m1 architecture homebrew:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/uninstall.sh)"
  1. Clean up any lingering files from 1 and 3 that the uninstall script tells you about
  2. Re-install homebrew (see the site) and restore your homebrew configuration using brew bundle
  3. Delete all python versions you have via pyenv (this could also be step 1 but I did it here)
  4. Re-download the versions you want with pyenv
  5. You're saved! Hopefully.
Allen N
  • 59
  • 4
-1

i had an issue with 'abort 6' when importing 'requests' package after updating to catalina. while searching for a solution, i was lead to this page. unfortunately none of the above worked for me, however...

updating to python 3.8 manually from python.org seemed to solve this issue very easily for me. i had to reinstall all my packages (w/ pip3) as i came across errors, but that wasn't so bad.

i don't see any of my projects having an issue with python3.8 so far (been using 3.7 for a while)

hope this helps someone! thanks for all the additional suggestions and efforts!

greenhouse
  • 1,231
  • 14
  • 19
-3

python3.6 -c 'import requests; requests.get("https://www.apple.com/")'

Try using this. Check if this works for you.

Nitin
  • 246
  • 1
  • 7