SSL: CERTIFICATE_VERIFY_FAILED error with python3 on macOS 10.15
Asked Answered
A

7

13

/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.)

Alben answered 23/8, 2019 at 16:51 Comment(2)
Btw #44261944 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.Alben
I think that question is talking about installer provided by PSF.Gunwale
A
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).

Alben answered 23/8, 2019 at 16:57 Comment(3)
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 @Rathbun answer) before doing rsync, finally it worked.Welladvised
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.Gunwale
Update: Apple’s attitude is “use Requests instead”.Gunwale
R
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.

Rathbun answered 27/9, 2019 at 4:43 Comment(3)
Use -p with mkdirif it says "No such file or directory".Popery
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 @Alben says below, that's irrelevant because python3 -c 'import ssl; print(ssl.get_default_verify_paths())' doesn't careTinkle
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/Tinkle
A
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).

Alben answered 23/8, 2019 at 16:57 Comment(3)
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 @Rathbun answer) before doing rsync, finally it worked.Welladvised
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.Gunwale
Update: Apple’s attitude is “use Requests instead”.Gunwale
G
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.

Gunwale answered 21/2, 2020 at 8:43 Comment(0)
S
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
Spires answered 4/7, 2021 at 18:2 Comment(3)
when i ran first line it says that pip command not found how can i solve this?Commissioner
This means that you do not have pip3 and pip3 packages installed. Therefore you can skip this step. Xcode command line tools contains pip3.Spires
I get an "ERROR: unknown command "requests"Espresso
G
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.
Gustafsson answered 20/10, 2022 at 2:48 Comment(0)
G
-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!

Griggs answered 2/6, 2020 at 23:36 Comment(0)
E
-3

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

Try using this. Check if this works for you.

Eucaine answered 27/9, 2019 at 5:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.