15

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

2
  • Btw stackoverflow.com/questions/44261444/… 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. Commented Aug 23, 2019 at 16:52
  • I think that question is talking about installer provided by PSF. Commented Feb 21, 2020 at 8:44

7 Answers 7

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Use -p with mkdirif it says "No such file or directory".
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
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/
13

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

3 Comments

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.
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.
Update: Apple’s attitude is “use Requests instead”.
3

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.

Comments

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 

3 Comments

when i ran first line it says that pip command not found how can i solve this?
This means that you do not have pip3 and pip3 packages installed. Therefore you can skip this step. Xcode command line tools contains pip3.
I get an "ERROR: unknown command "requests"
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.

Comments

-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!

Comments

-3

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

Try using this. Check if this works for you.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.