SSLError with Python 3.6.x on macOS Sierra

SSLError

Have you ran into trouble with SSLErrors after upgrading to Python 3.6 on macOS Sierra?  For me, my first encounter was downloading the bokeh sample data (included here).

Python 3.6.0 (v3.6.0:41df79263a11, Dec 22 2016, 17:23:13)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import bokeh.sampledata
>>> bokeh.sampledata.download()
Using data directory: /Users/chad/.bokeh/data
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 1318, in do_open
    encode_chunked=req.has_header('Transfer-encoding'))
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 1239, in request
    self._send_request(method, url, body, headers, encode_chunked)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 1285, in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 1234, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 1026, in _send_output
    self.send(msg)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 964, in send
    self.connect()
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 1400, in connect
    server_hostname=server_hostname)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py", line 401, in wrap_socket
    _context=self, _session=session)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py", line 808, in __init__
    self.do_handshake()
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py", line 1061, in do_handshake
    self._sslobj.do_handshake()
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py", line 683, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:749)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/chad/Library/Python/3.6/lib/python/site-packages/bokeh/sampledata/__init__.py", line 81, in download
    _getfile(base_url, file_name, data_dir, progress=progress)
  File "/Users/chad/Library/Python/3.6/lib/python/site-packages/bokeh/sampledata/__init__.py", line 87, in _getfile
    url = urlopen(file_url)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 223, in urlopen
    return opener.open(url, data, timeout)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 526, in open
    response = self._open(req, data)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 544, in _open
    '_open', req)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 504, in _call_chain
    result = func(*args)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 1361, in https_open
    context=self._context, check_hostname=self._check_hostname)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 1320, in do_open
    raise URLError(err)
urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:749)>

I finally got a chance to research exactly what was wrong.  Given that Python 3.5 was working on my machine and 3.6 was working on several linux machines, I thought that it could have been an issue with Python 3.6, unlikely as it may be.  After no bug fix version was released I realized that it must be my configuration.
Searching, I found one result related to this in the Python issue tracker: Issue 28150.  One answerer points out that Python on macOS no longer relies on Apple’s version of OpenSSL, instead it is shipped with a new one.  The gotcha: this new one does not have trust certificates installed.  All this is detailed in the Readme.

The Installer Readme

So, as the Python issue tracker mentioned, there is an entry in the installer readme.  Perhaps I should read these closer…

Certificate verification and OpenSSL
**NEW** This variant of Python 3.6 now includes its own private copy of OpenSSL 1.0.2.  Unlike previous releases, the deprecated Apple-supplied OpenSSL libraries are no longer used.  This also means that the trust certificates in system and user keychains managed by the Keychain Access application and the security command line utility are no longer used as defaults by the Python ssl module.  For 3.6.0, a sample command script is included in /Applications/Python 3.6 to install a curated bundle of default root certificates from the third-party certifi package (https://pypi.python.org/pypi/certifi).  If you choose to use certifi, you should consider subscribing to the project’s email update service to be notified when the certificate bundle is updated.
The bundled pip included with the Python 3.6 installer has its own default certificate store for verifying download connections.

Two Solutions

There are two solutions as mentioned:

  • Install the certifi package.
  • Run the download script provided with the installer – /Applications/Python 3.6/Install Certificates.command.

For myself, I ran the bundled script and everything seems to be functioning fine.  It seems more than a little odd that this was not done on installation.
 
 

18 Comments

  1. marc

    thank you so much!
    I spent two days on this problem. First, my access to online database stopped, and after two days searching for this error, you provided the solution
    If you ever visit Zurich, I will buy you a beer or two (or anything else)
    Best from Switzerland
    Marc

  2. Nelson Lim Tyng Xian

    Thanks for the solution so much. I really appreciated that. I was struggling to look for the solution, ended up this is the only solution I get, the rest just told me that it is a ssl problem. Thanks again!!

  3. @Chad, If you see Install Certificate.command, it is again nothing but installing certifi package
    26 def main():
    25 openssl_dir, openssl_cafile = os.path.split(
    24 ssl.get_default_verify_paths().openssl_cafile)
    23
    22 print(” — pip install –upgrade certifi”)
    21 subprocess.check_call([sys.executable,
    20 “-E”, “-s”, “-m”, “pip”, “install”, “–upgrade”, “certifi”])

  4. Samrat Ghosh

    I did try everything but I still getting the same error
    File “/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py”, line 1239, in request
    self._send_request(method, url, body, headers, encode_chunked)
    File “/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py”, line 1285, in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
    File “/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py”, line 1234, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
    File “/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py”, line 1026, in _send_output
    self.send(msg)
    File “/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py”, line 964, in send
    self.connect()
    File “/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py”, line 1400, in connect
    server_hostname=server_hostname)
    File “/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py”, line 401, in wrap_socket
    _context=self, _session=session)
    File “/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py”, line 808, in __init__
    self.do_handshake()
    File “/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py”, line 1061, in do_handshake
    self._sslobj.do_handshake()
    File “/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py”, line 683, in do_handshake
    self._sslobj.do_handshake()
    ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:749)

  5. Matthew

    I just received a new MacBook Pro, and am trying to get my development environment setup. The exact same code has worked on Linux and Windows 10. I have already installed certifi, and the otherwise mentioned install script does not exist in my install (from MacPorts). I am using Python 3.5. Any ideas? The is being generated as a result of using this library: https://github.com/yoavaviram/python-amazon-simple-product-api
    File “/opt/local/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/urllib/request.py”, line 484, in _open
    ‘_open’, req)
    File “/opt/local/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/urllib/request.py”, line 444, in _call_chain
    result = func(*args)
    File “/opt/local/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/urllib/request.py”, line 1297, in https_open
    context=self._context, check_hostname=self._check_hostname)
    File “/opt/local/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/urllib/request.py”, line 1256, in do_open
    raise URLError(err)
    urllib.error.URLError:

    • Does the error have any further message? From the docs, URLError has a reason attribute that should contain more info.

      exception urllib.error.URLError
      The handlers raise this exception (or derived exceptions) when they run into a problem. It is a subclass of OSError.
      reason
      The reason for this error. It can be a message string or another exception instance.
      Changed in version 3.3: URLError has been made a subclass of OSError instead of IOError.

  6. Ivan Stamenkovic

    I was able to run: pip3 install certifi
    After installing, I checked and received message:
    pip3 install certifi
    Requirement already satisfied: certifi in /Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages
    Now my challenge is how to follow the second instruction from the link you provided:
    “Reference the installed certificate authority (CA) bundle, you can use the built-in function:
    >>> import certifi
    >>> certifi.where()
    ‘/usr/local/lib/python2.7/site-packages/certifi/cacert.pem’
    As I installed certifi for Python 3, I modified above as follows:
    >>> import certifi
    >>> certifi.where()
    ‘/usr/local/lib/python3.6/site-packages/certifi/cacert.pem’
    I then copy all above and paste in terminal, but I get two types of errors as below:
    Ivans-MacBook:~ ivanstamenkovic$ >>> import certifi
    -bash: syntax error near unexpected token `>’
    Ivans-MacBook:~ ivanstamenkovic$
    Ivans-MacBook:~ ivanstamenkovic$ >>> certifi.where()
    -bash: syntax error near unexpected token `>’
    Ivans-MacBook:~ ivanstamenkovic$ ‘/usr/local/lib/python3.6/site-packages/certifi/cacert.pem’
    -bash: /usr/local/lib/python3.6/site-packages/certifi/cacert.pem: No such file or directory
    The location of Python 3 is:
    Ivans-MacBook:~ ivanstamenkovic$ which python3
    /Library/Frameworks/Python.framework/Versions/3.6/bin/python3
    Now, I am going to try the second solution but I can’t find “Install Certificates.command”
    FYI:I have confirmed that the following are installed:
    Python 3.6.2
    Feedparser 5.2.1
    Eclipse Juno
    LiClipse
    Homebrew 1.3.1
    TextWrangler
    I am running Mac OS Sierra 10.12.5

  7. Nathan

    I have followed these instructions and have had no success. Is there an updated fix?

  8. Venkat

    I have installed python3.6 using home-brew and didn’t find the Install Certificates.command under Applications. Please suggest how to fix the ssl issue the installed the python using home-brew.

  9. Anand Prasad

    Thanks Chad, Your instructions worked like a charm. It really helped me to solve Oracle Cloud CLI installation on my new Mac OS. Thanks

  10. Anto

    You rock, Chad. I’ve had this problem in the past, fixed it, but could not remember how to fix it again later.
    Maybe StackOverflow folks could use this solution as well. Keep it going.

Leave a Reply