51

I installed python 3.6 using

brew install python3

and tried to download a file with six.moves.urllib.request.urlretrieve from an https, but it throws the error

ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:749)

In the Python installation (from .pkg), the README indicates that one needs to run the Install Certificates.command after the installation to

  1. install certifi
  2. symlink the certification path to certify path

to be able to use certificates.

However, in brew install, this file does not exist and it does not seem to be run.

4
  • 1
    Executing /Applications/Python\ 3.6/Install\ Certificates.command in Terminal fixed this problem with my homebrew python3 installation. Commented Feb 4, 2019 at 15:07
  • 1
    Given the popularity of this question, I fielded a issue to brew. Commented Jul 19, 2019 at 22:54
  • export SSL_CERT_DIR=/etc/ssl/certs worked for me in Mac OS Big Sur. Commented Oct 8, 2021 at 20:54
  • This comment by robo-corg points out the root of the cause. I. e., it is the missing /opt/homebrew/etc/[email protected]/cert.pem. Now on a mac, you have that file in /private/etc/ssl/. So running, ln -s /private/etc/ssl/cert.pem /opt/homebrew/etc/[email protected]/cert.pem sym links the certificate. And, that resolved the issue. Commented May 8, 2023 at 6:36

9 Answers 9

164

It seems that, for some reason, Brew has not run the Install Certificates.command that comes in the Python3 bundle for Mac. The solution to this issue is to run the following script (copied from Install Certificates.command) after brew install python3:

# install_certifi.py # # sample script to install or update a set of default Root Certificates # for the ssl module. Uses the certificates provided by the certifi package: # https://pypi.python.org/pypi/certifi import os import os.path import ssl import stat import subprocess import sys STAT_0o775 = ( stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR | stat.S_IRGRP | stat.S_IWGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH ) def main(): openssl_dir, openssl_cafile = os.path.split( ssl.get_default_verify_paths().openssl_cafile) print(" -- pip install --upgrade certifi") subprocess.check_call([sys.executable, "-E", "-s", "-m", "pip", "install", "--upgrade", "certifi"]) import certifi # change working directory to the default SSL directory os.chdir(openssl_dir) relpath_to_certifi_cafile = os.path.relpath(certifi.where()) print(" -- removing any existing file or link") try: os.remove(openssl_cafile) except FileNotFoundError: pass print(" -- creating symlink to certifi certificate bundle") os.symlink(relpath_to_certifi_cafile, openssl_cafile) print(" -- setting permissions") os.chmod(openssl_cafile, STAT_0o775) print(" -- update complete") if __name__ == '__main__': main() 
Sign up to request clarification or add additional context in comments.

9 Comments

What does one do, if one does not have root access / sudo rights? Thanks.
I ran the above command and it seemed to work successfully, but I am still getting the error. Any ideas on how to debug this?
For reference, the source of this script is here: github.com/python/cpython/blob/master/Mac/BuildScript/resources/…
@tommy.carstensen you will have to just run this for your own virtual environments
I had to add import ssl; ssl._create_default_https_context = ssl._create_stdlib_context to my code for it to work.
|
37

My solution for Mac OS X:

1) Upgrade to Python 3.6.5 using the native app Python installer downloaded from the official Python language website https://www.python.org/downloads/

I've found that this installer is taking care of updating the links and symlinks for the new Python a lot better than homebrew.

2) Install a new certificate using "./Install Certificates.command" which is in the refreshed Python 3.6 directory

cd "/Applications/Python 3.6/" sudo "./Install Certificates.command"

6 Comments

Thanks! Worked for me, and I'm on 3.8 (changed the command appropriately to the Python 3.8 directory).
There is no Python folder in my Applications, and I could not locate it on my machine. Any ideas how can I fix the issue for my case?
@talha06 - In order to know where Python is located on your computer, open the python shell typing python or python3 then import sys and print('\n'.join(sys.path)) Or you can type this command in the terminal python -c "import sys; print('\n'.join(sys.path))"
After 2 dys of searching. this is what worked for me. Didn't even make it to the approved solution.
Can't believe that this is still the best answer 6 years later, but it worked for me! Seems like a flaw!
|
26
  • find out default cafile:
python -c 'import ssl; print(ssl.get_default_verify_paths().openssl_cafile)' 

/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.7/etc/ssl/cert.pem

sudo mkdir -p /Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.7/etc/ssl/certs 
  • find out ca file of certifi
python -c 'import certifi; print(certifi.where())' 

'/usr/local/lib/python3.7/site-packages/certifi/cacert.pem'

  • copy to
sudo cp /usr/local/lib/python3.7/site-packages/certifi/cacert.pem /Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.7/etc/ssl/certs/cert.pem 

5 Comments

This did not work for me on a conda python environment, using conda python. I tried copying the certs in three different directories: ssl, ssl/crt, etc/ssl/certs . I have found no solution so far.
@user1255933 how did you solve this?
This is the correct answer to this question, awesome way to find the default cert.pem!
Thank you. My work uses Zscaler and I was using a miniconda python install. This gave me the clue I needed to find the offending openssl_cafile. I copied the Zscaler root CA over /Users/xxx/miniconda3/ssl/cert.pem and my problem was solved.
The output from python -c 'import ssl; print(ssl.get_default_verify_paths().openssl_cafile)' was a non-existing file for me. I simply copied the file at the path from python -c 'import certifi; print(certifi.where())' to the path of the former command. The exact steps in this answer did not work for me. Using RHEL7
12

For temporary, following will disable the ssl checking,

import ssl ssl._create_default_https_context = ssl._create_unverified_context 

2 Comments

This solves the immediate problem, but is NOT RECOMMENDED: you run the risk of putting a vulnerable service into production this way.
This is a bad idea. It makes using TLS pointless.
9

If you need to make your local root certificate (e.g. local_RootCA.crt) become trusted by python, you can add it into the end of certifi/cacert.pem file:

cat local_RootCA.crt >> `python -c 'import certifi; print(certifi.where())'` 

That solution works good for macos brew python 3 installation as well.

1 Comment

After a day of trying different things in this and other SOF conversations, this is what worked for us. Thanks!
4

You will not be able to find this file in Application -> Python folder.

On MAC Press Command + Space to open Spotlight Search and type 'Install Certificates.command', then execute it. This solution resolved the issue for me.

Comments

1

positionning SSL_CERT_FILE env var to your ca file also works and it is not invasive.

Comments

0

I had the same issue with Python 3.11. I went to the Python directory and did the following steps. I did the first step because the terminal did not have the permission to do this action.

  1. chmod +x Install\ Certificates.command
  2. ./Install\ Certificates.command

After these two steps, my application is executable!

Comments

0

I did a combination of two of the above answers:

I ran:

python3 -c 'import ssl; print(ssl.get_default_verify_paths().openssl_cafile)' 

to get where Python thought the cert.pem file should be and there was nothing there. For me it was /Library/Frameworks/Python.framework/Versions/3.10/etc/openssl/cert.pem but I expect others installations to be different.

I ran:

ls /private/etc/ssl/ 

Which showed that there was a cert.pem there.

I changed directory to where Python openssl looked for the cert.pem file. For me that was:

cd /Library/Frameworks/Python.framework/Versions/3.10/etc/openssl/ 

Then I created a link from the one in /private to the openssl directory:

ln -s /private/etc/ssl/cert.pem cert.pem 

After that, the error went away.

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.