Boto3: SSL validation failed (_ssl.c:1051) Python 3.7

Created on 22 Feb 2019  路  8Comments  路  Source: boto/boto3

META:

Windows 10
python 3.7
pip 18.1
awscli==1.16.110
boto==2.49.0
boto3==1.9.100
botocore==1.12.100
certifi==2018.11.29

Issue Description

Since last week, I've been encountering an issue where if I try to use boto3 to upload to my S3 bucket, I get an error:

SSLError: SSL validation failed for https://s3.amazonaws.com/ [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1051)

I've tried most of the suggestions I could find but still am having this issue.

Test Case from Fresh Installation

On a windows 10 computer, I tried a fresh install of Anaconda for Python 3.7.
Created new credentials in AWS IAM.
pip install awscli
aws configure
Entered in AWS credentials and configuration information.
pip install boto3

Attempted to run the following:

import boto3
s3 = boto3.resource('s3')
for bucket in s3.buckets.all():
    print(bucket.name)

Traceback


SSLCertVerificationError Traceback (most recent call last)
~AppData\Local\Continuum\anaconda3\lib\site-packages\urllib3\connectionpool.py in urlopen(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, **response_kw)
599 body=body, headers=headers,
--> 600 chunked=chunked)
601

~AppData\Local\Continuum\anaconda3\lib\site-packages\urllib3\connectionpool.py in _make_request(self, conn, method, url, timeout, chunked, **httplib_request_kw)
342 try:
--> 343 self._validate_conn(conn)
344 except (SocketTimeout, BaseSSLError) as e:

~AppData\Local\Continuum\anaconda3\lib\site-packages\urllib3\connectionpool.py in _validate_conn(self, conn)
838 if not getattr(conn, 'sock', None): # AppEngine might not have .sock
--> 839 conn.connect()
840

~AppData\Local\Continuum\anaconda3\lib\site-packages\urllib3\connection.py in connect(self)
343 server_hostname=server_hostname,
--> 344 ssl_context=context)
345

~AppData\Local\Continuum\anaconda3\lib\site-packages\urllib3\util\ssl_.py in ssl_wrap_socket(sock, keyfile, certfile, cert_reqs, ca_certs, server_hostname, ssl_version, ciphers, ssl_context, ca_cert_dir)
343 if HAS_SNI and server_hostname is not None:
--> 344 return context.wrap_socket(sock, server_hostname=server_hostname)
345

~AppData\Local\Continuum\anaconda3\lib\ssl.py in wrap_socket(self, sock, server_side, do_handshake_on_connect, suppress_ragged_eofs, server_hostname, session)
411 context=self,
--> 412 session=session
413 )

~AppData\Local\Continuum\anaconda3\lib\ssl.py in _create(cls, sock, server_side, do_handshake_on_connect, suppress_ragged_eofs, server_hostname, context, session)
852 raise ValueError("do_handshake_on_connect should not be specified for non-blocking sockets")
--> 853 self.do_handshake()
854 except (OSError, ValueError):

~AppData\Local\Continuum\anaconda3\lib\ssl.py in do_handshake(self, block)
1116 self.settimeout(None)
-> 1117 self._sslobj.do_handshake()
1118 finally:

SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1051)

During handling of the above exception, another exception occurred:

SSLError Traceback (most recent call last)
~AppData\Local\Continuum\anaconda3\lib\site-packages\botocore\httpsession.py in send(self, request)
257 preload_content=False,
--> 258 decode_content=False,
259 )

~AppData\Local\Continuum\anaconda3\lib\site-packages\urllib3\connectionpool.py in urlopen(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, **response_kw)
637 retries = retries.increment(method, url, error=e, _pool=self,
--> 638 _stacktrace=sys.exc_info()[2])
639 retries.sleep()

~AppData\Local\Continuum\anaconda3\lib\site-packages\urllib3\util\retry.py in increment(self, method, url, response, error, _pool, _stacktrace)
342 # Disabled, indicate to re-raise the error.
--> 343 raise six.reraise(type(error), error, _stacktrace)
344

~AppData\Local\Continuum\anaconda3\lib\site-packages\urllib3\packages\six.py in reraise(tp, value, tb)
684 if value.__traceback__ is not tb:
--> 685 raise value.with_traceback(tb)
686 raise value

~AppData\Local\Continuum\anaconda3\lib\site-packages\urllib3\connectionpool.py in urlopen(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, **response_kw)
599 body=body, headers=headers,
--> 600 chunked=chunked)
601

~AppData\Local\Continuum\anaconda3\lib\site-packages\urllib3\connectionpool.py in _make_request(self, conn, method, url, timeout, chunked, **httplib_request_kw)
342 try:
--> 343 self._validate_conn(conn)
344 except (SocketTimeout, BaseSSLError) as e:

~AppData\Local\Continuum\anaconda3\lib\site-packages\urllib3\connectionpool.py in _validate_conn(self, conn)
838 if not getattr(conn, 'sock', None): # AppEngine might not have .sock
--> 839 conn.connect()
840

~AppData\Local\Continuum\anaconda3\lib\site-packages\urllib3\connection.py in connect(self)
343 server_hostname=server_hostname,
--> 344 ssl_context=context)
345

~AppData\Local\Continuum\anaconda3\lib\site-packages\urllib3\util\ssl_.py in ssl_wrap_socket(sock, keyfile, certfile, cert_reqs, ca_certs, server_hostname, ssl_version, ciphers, ssl_context, ca_cert_dir)
343 if HAS_SNI and server_hostname is not None:
--> 344 return context.wrap_socket(sock, server_hostname=server_hostname)
345

~AppData\Local\Continuum\anaconda3\lib\ssl.py in wrap_socket(self, sock, server_side, do_handshake_on_connect, suppress_ragged_eofs, server_hostname, session)
411 context=self,
--> 412 session=session
413 )

~AppData\Local\Continuum\anaconda3\lib\ssl.py in _create(cls, sock, server_side, do_handshake_on_connect, suppress_ragged_eofs, server_hostname, context, session)
852 raise ValueError("do_handshake_on_connect should not be specified for non-blocking sockets")
--> 853 self.do_handshake()
854 except (OSError, ValueError):

~AppData\Local\Continuum\anaconda3\lib\ssl.py in do_handshake(self, block)
1116 self.settimeout(None)
-> 1117 self._sslobj.do_handshake()
1118 finally:

SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1051)

During handling of the above exception, another exception occurred:

SSLError Traceback (most recent call last)
in
4 s3 = boto3.resource('s3')
5 # Print out bucket names
----> 6 for bucket in s3.buckets.all():
7 print(bucket.name)

~AppData\Local\Continuum\anaconda3\lib\site-packages\boto3\resources\collection.py in __iter__(self)
81
82 count = 0
---> 83 for page in self.pages():
84 for item in page:
85 yield item

~AppData\Local\Continuum\anaconda3\lib\site-packages\boto3\resources\collection.py in pages(self)
159 self._parent.meta.service_name,
160 self._py_operation_name, params)
--> 161 pages = [getattr(client, self._py_operation_name)(**params)]
162
163 # Now that we have a page iterator or single page of results

~AppData\Local\Continuum\anaconda3\lib\site-packages\botocore\client.py in _api_call(self, args, *kwargs)
355 "%s() only accepts keyword arguments." % py_operation_name)
356 # The "self" in this scope is referring to the BaseClient.
--> 357 return self._make_api_call(operation_name, kwargs)
358
359 _api_call.__name__ = str(py_operation_name)

~AppData\Local\Continuum\anaconda3\lib\site-packages\botocore\client.py in _make_api_call(self, operation_name, api_params)
646 else:
647 http, parsed_response = self._make_request(
--> 648 operation_model, request_dict, request_context)
649
650 self.meta.events.emit(

~AppData\Local\Continuum\anaconda3\lib\site-packages\botocore\client.py in _make_request(self, operation_model, request_dict, request_context)
665 def _make_request(self, operation_model, request_dict, request_context):
666 try:
--> 667 return self._endpoint.make_request(operation_model, request_dict)
668 except Exception as e:
669 self.meta.events.emit(

~AppData\Local\Continuum\anaconda3\lib\site-packages\botocore\endpoint.py in make_request(self, operation_model, request_dict)
100 logger.debug("Making request for %s with params: %s",
101 operation_model, request_dict)
--> 102 return self._send_request(request_dict, operation_model)
103
104 def create_request(self, params, operation_model=None):

~AppData\Local\Continuum\anaconda3\lib\site-packages\botocore\endpoint.py in _send_request(self, request_dict, operation_model)
135 request, operation_model, context)
136 while self._needs_retry(attempts, operation_model, request_dict,
--> 137 success_response, exception):
138 attempts += 1
139 # If there is a stream associated with the request, we need

~AppData\Local\Continuum\anaconda3\lib\site-packages\botocore\endpoint.py in _needs_retry(self, attempts, operation_model, request_dict, response, caught_exception)
229 event_name, response=response, endpoint=self,
230 operation=operation_model, attempts=attempts,
--> 231 caught_exception=caught_exception, request_dict=request_dict)
232 handler_response = first_non_none_response(responses)
233 if handler_response is None:

~AppData\Local\Continuum\anaconda3\lib\site-packages\botocore\hooks.py in emit(self, event_name, *kwargs)
354 def emit(self, event_name, *
kwargs):
355 aliased_event_name = self._alias_event_name(event_name)
--> 356 return self._emitter.emit(aliased_event_name, *kwargs)
357
358 def emit_until_response(self, event_name, *
kwargs):

~AppData\Local\Continuum\anaconda3\lib\site-packages\botocore\hooks.py in emit(self, event_name, *kwargs)
226 handlers.
227 """
--> 228 return self._emit(event_name, kwargs)
229
230 def emit_until_response(self, event_name, *
kwargs):

~AppData\Local\Continuum\anaconda3\lib\site-packages\botocore\hooks.py in _emit(self, event_name, kwargs, stop_on_response)
209 for handler in handlers_to_call:
210 logger.debug('Event %s: calling handler %s', event_name, handler)
--> 211 response = handler(**kwargs)
212 responses.append((handler, response))
213 if stop_on_response and response is not None:

~AppData\Local\Continuum\anaconda3\lib\site-packages\botocore\retryhandler.py in __call__(self, attempts, response, caught_exception, **kwargs)
181
182 """
--> 183 if self._checker(attempts, response, caught_exception):
184 result = self._action(attempts=attempts)
185 logger.debug("Retry needed, action of: %s", result)

~AppData\Local\Continuum\anaconda3\lib\site-packages\botocore\retryhandler.py in __call__(self, attempt_number, response, caught_exception)
249 def __call__(self, attempt_number, response, caught_exception):
250 should_retry = self._should_retry(attempt_number, response,
--> 251 caught_exception)
252 if should_retry:
253 if attempt_number >= self._max_attempts:

~AppData\Local\Continuum\anaconda3\lib\site-packages\botocore\retryhandler.py in _should_retry(self, attempt_number, response, caught_exception)
275 # If we've exceeded the max attempts we just let the exception
276 # propogate if one has occurred.
--> 277 return self._checker(attempt_number, response, caught_exception)
278
279

~AppData\Local\Continuum\anaconda3\lib\site-packages\botocore\retryhandler.py in __call__(self, attempt_number, response, caught_exception)
315 for checker in self._checkers:
316 checker_response = checker(attempt_number, response,
--> 317 caught_exception)
318 if checker_response:
319 return checker_response

~AppData\Local\Continuum\anaconda3\lib\site-packages\botocore\retryhandler.py in __call__(self, attempt_number, response, caught_exception)
221 elif caught_exception is not None:
222 return self._check_caught_exception(
--> 223 attempt_number, caught_exception)
224 else:
225 raise ValueError("Both response and caught_exception are None.")

~AppData\Local\Continuum\anaconda3\lib\site-packages\botocore\retryhandler.py in _check_caught_exception(self, attempt_number, caught_exception)
357 # the MaxAttemptsDecorator is not interested in retrying the exception
358 # then this exception just propogates out past the retry code.
--> 359 raise caught_exception

~AppData\Local\Continuum\anaconda3\lib\site-packages\botocore\endpoint.py in _do_get_response(self, request, operation_model)
198 http_response = first_non_none_response(responses)
199 if http_response is None:
--> 200 http_response = self._send(request)
201 except HTTPClientError as e:
202 return (None, e)

~AppData\Local\Continuum\anaconda3\lib\site-packages\botocore\endpoint.py in _send(self, request)
242
243 def _send(self, request):
--> 244 return self.http_session.send(request)
245
246

~AppData\Local\Continuum\anaconda3\lib\site-packages\botocore\httpsession.py in send(self, request)
274 return http_response
275 except URLLib3SSLError as e:
--> 276 raise SSLError(endpoint_url=request.url, error=e)
277 except (NewConnectionError, socket.gaierror) as e:
278 raise EndpointConnectionError(endpoint_url=request.url, error=e)

SSLError: SSL validation failed for https://s3.amazonaws.com/ [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1051)

closing-soon ssl

All 8 comments

This became an issue for me sometime after 2/7/2019.
This issue occurs in all versions of Python 3.7. I'll try switching to python 3.6 to see if this is still an issue.

My current work around is to set the verify to False, i.e. s3 = boto3.resource('s3', verify=False). Hopefully this issue can be resolved soon.

Python 3.6.8 64bit

I tried a fresh installation of python 3.6.8, ran the same script, and got the following error this time:

botocore.exceptions.SSLError: SSL validation failed for https://s3.amazonaws.com/ [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:852)

pip freeze

awscli==1.16.110
boto3==1.9.100
botocore==1.12.100
colorama==0.3.9
docutils==0.14
jmespath==0.9.3
pyasn1==0.4.5
python-dateutil==2.8.0
PyYAML==3.13
rsa==3.4.2
s3transfer==0.2.0
six==1.12.0
urllib3==1.24.1

Python 3.6.6 32bit

Fresh installation. Error:

botocore.exceptions.SSLError: SSL validation failed for https://s3.amazonaws.com/?encoding-type=url [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:841)

pip freeze

boto3==1.9.100
botocore==1.12.100
docutils==0.14
jmespath==0.9.3
python-dateutil==2.8.0
s3transfer==0.2.0
six==1.12.0
urllib3==1.24.1

This might be related to the CA bundle being used for connections. Can you try a few things?

  1. Does a request other aws services fail?
import boto3
boto3.client('ec2').describe_instances()
boto3.client('sts').get_caller_identity()
  1. Does using urllib3 directly work? I'd try a non AWS site to see if that fails.
>>> import urllib3
>>> https = urllib3.PoolManager(cert_reqs='CERT_REQUIRED')
>>> response = https.request('GET', 'https://httpbin.org/robots.txt')
>>> response.status
200

Before reinstalling pyOpenSSL

Suggestion 1, I got the following errors:
Attempting: boto3.client('ec2').describe_instances()

SSLError: SSL validation failed for https://ec2.us-east-1.amazonaws.com/ [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1051)

Attempting: boto3.client('sts').get_caller_identity()

SSLError: SSL validation failed for https://sts.amazonaws.com/ [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1051)

For suggestion 2, I got response status 503 the first time I ran that code. On subsequent runs, I got the following error:

MaxRetryError: HTTPSConnectionPool(host='httpbin.org', port=443): Max retries exceeded with url: /robots.txt (Caused by SSLError(SSLError("bad handshake: Error([('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')])")))

After reinstalling pyOpenSSL

I tried pip install -U pyopenssl to see if it affected my results.

The errors I received for running the first code snippet are unchanged, but now get a response status 200 for calling urllib3 direct in the second code snippet.

@MStokholm - Sorry for the delay in addressing your issue. Are you still getting the error with latest version of boto3(1.9.176) ?

Here is some resource that might help:
https://stackoverflow.com/questions/32946050/ssl-certificate-verify-failed-in-aws-cli

Please let me know if you have any questions.

This issue has been automatically closed because there has been no response to our request for more information from the original author. With only the information that is currently in the issue, we don't have enough information to take action. Please reach out if you have or find the answers we need so that we can investigate further.

Hi, not OP and not sure what your protocols w/r/t closed issues are but I am a pipenv dev and I have worked closely with the requests folks and I both ran into this issue (and was not provided with a helpful error message) and have seen it before.

Is there some reason why you need to bundle certificates with the library? It's not really a best practice and it leads to workarounds like the one in the linked SO post, which advises using --no-verify-ssl (when using AWSCLI that is, not sure if that translates to boto3). It basically defeats the purpose of using certificates at all if the advice is to just disable verification whenever there's an issue

I have got the solution for this.

Don't install boto3 using pip/pip3.

Use following steps::

$ git clone https://github.com/boto/boto3.git
$ cd boto3
$ virtualenv venv
...
$ . venv/bin/activate
$ pip install -r requirements.txt
$ pip install -e .

It worked for me. Initially I was facing the same SSL Validation Exception problem. Then I uninstalled the boto3 (pip3 uninstall boto3) and re-installed it using virtualenv as stated above. Now, it is working fine.

Was this page helpful?
0 / 5 - 0 ratings