Python ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:748)
Asked Answered
M

7

13

I'm using [geopy][1] in a Python 3.6 application and I have to run it on an outdated machine that uses Windows 2012 Server. The problem arises when from the application this library is called on this server since it returns the following error:

File "C:\ServAPI\Util.py", line 12, in getLocation
location = geolocator.geocode(name)
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36-32\lib\site-packages\geopy\geocoders\osm.py", line 193, in geocode
self._call_geocoder(url, timeout=timeout), exactly_one
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36-32\lib\site-packages\geopy\geocoders\base.py", line 171, in _call_geocoder
raise GeocoderServiceError(message)
geopy.exc.GeocoderServiceError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:748)

How can I fix this problem? I am running Python 3.6.0 on Windows 2012 Server

UPDATE

The code is the next:

from geopy.geocoders import Nominatim
from geopy.exc import GeocoderTimedOut
def getLocation(name):
    geolocator = Nominatim()
    try:
        location = geolocator.geocode(name, timeout=5)
        return location
    except GeocoderTimedOut as e:
        print("Error: geocode failed on input %s with message %s" % (e.msg))
Mciver answered 4/10, 2017 at 8:18 Comment(0)
M
2

Finally, I have the solution:

It is possible that win2012 has outdated SSL library. So, the solution is to indicate explicitly that schema is http:

The correct code is:

from geopy.geocoders import Nominatim
from geopy.exc import GeocoderTimedOut

def getLocation(name):
    geolocator = Nominatim(scheme='http')
    try:
        location = geolocator.geocode(name, timeout=5)
        return location
    except GeocoderTimedOut as e:
        print("Error: geocode failed on input %s with message %s" % (e.msg))
Mciver answered 3/11, 2017 at 8:54 Comment(2)
This answer did not work in 2021 with Windows 10 answer from Brad Ahrens worked for me.Natterjack
Sure, I did this question 4 years ago. Please, update the question and add the solution for your environment!Mciver
P
11

I had the same problem, but ended up having to install SSL and Certifi as well. I'm not sure if anyone else will have this problem, but if so, here is how I solved it.

First install the Certifi and SSL packages, then

import certifi
import ssl
import geopy.geocoders
from geopy.geocoders import Nominatim
ctx = ssl.create_default_context(cafile=certifi.where())
geopy.geocoders.options.default_ssl_context = ctx

geolocator = Nominatim(scheme='http')
location = geolocator.reverse("48.8588443, 2.2943506")

print(location.address)
print (location.raw)

Then, the result is:

Tour Eiffel, 5, Avenue Anatole France, Gros-Caillou, 7e, Paris, Île-de-France, France métropolitaine, 75007, France
{'place_id': '62005962', 'licence': 'Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright', 'osm_type': 'way', 'osm_id': '5013364', 'lat': '48.8582602', 'lon': '2.29449905431968', 'display_name': 'Tour Eiffel, 5, Avenue Anatole France, Gros-Caillou, 7e, Paris, Île-de-France, France métropolitaine, 75007, France', 'address': {'attraction': 'Tour Eiffel', 'house_number': '5', 'pedestrian': 'Avenue Anatole France', 'suburb': 'Gros-Caillou', 'city_district': '7e', 'city': 'Paris', 'county': 'Paris', 'state': 'Île-de-France', 'country': 'France', 'postcode': '75007', 'country_code': 'fr'}, 'boundingbox': ['48.8574753', '48.8590465', '2.2933084', '2.2956897']}
Phosphine answered 3/6, 2018 at 10:41 Comment(0)
C
3

This worked for me

import certifi
import ssl
import geopy.geocoders
from geopy.geocoders import Nominatim
ctx = ssl.create_default_context(cafile=certifi.where())
geopy.geocoders.options.default_ssl_context = ctx
nom = Nominatim(scheme = 'http')
nom.geocode('Empire State , Manhattan , NY')
Cerussite answered 4/6, 2018 at 20:17 Comment(0)
D
3

I have the same Problem and solve it by change create_default_context to _create_unverified_context and it worked.

import certifi
import ssl
import geopy.geocoders

from geopy.geocoders import Nominatim

ctx = ssl._create_unverified_context(cafile=certifi.where())
geopy.geocoders.options.default_ssl_context = ctx

locator = Nominatim(scheme='https', user_agent="Test")
location = locator.reverse("36.3215876,60.5253593")

print(location.raw)
Dillondillow answered 4/10, 2021 at 7:10 Comment(0)
J
3

For those who met this issue recently, this is my test result in 2021: in my environment, python 3.6.8 + geopy 2.2.0 + centos 7 works; python 2.7.18 + geopy 1.23.0 + centos 8 works as well; but python 2.7.5 + geopy 1.23.0 + centos 7 doesn't work and reports the certificate error.

Finally, I found the root cause, it's due to the expiration on Sept. 30 of the older 'DST' root cert used by LetsEncrypt; see https://letsencrypt.org/docs/dst-root-ca-x3-expiration-september-2021 . Python is affected if it uses OpenSSL below 1.1.0; see https://openssl.org/blog/blog/2021/09/13/LetsEncryptRootCertExpire.

And I made python 2.7.5 + geopy 1.23.0 + centos 7 + openssl 1.0.2k-fips work with workaround 1 which is removing the (DST Root CA X3) root certificate from the system certificate, the detailed steps are:

  1. Check DST Root is in /etc/pki/tls/certs/ca-bundle.crt, and ISRG Root X1 is in as well.
  2. Copy the "# DST Root CA X3" section into /etc/pki/ca-trust/source/blacklist directory as pem file
  3. run update-ca-trust
  4. Check DST Root is no longer in /etc/pki/tls/certs/ca-bundle.crt, and ISRG Root X1 is in ISRG Root X1.

Ref:

UPDATE: As pointed out by @rsc, update your ca-certificates may also work:

yum upgrade ca-certificates

Juryrig answered 8/10, 2021 at 7:46 Comment(1)
Let's Encrypt chains work properly with RHEL/CentOS 7 after updating to ca-certificates-2021.2.50-72.el7_9. There is no need to manually edit /etc/pki/tls/certs/ca-bundle.crt when applying the update.Burnley
M
2

Finally, I have the solution:

It is possible that win2012 has outdated SSL library. So, the solution is to indicate explicitly that schema is http:

The correct code is:

from geopy.geocoders import Nominatim
from geopy.exc import GeocoderTimedOut

def getLocation(name):
    geolocator = Nominatim(scheme='http')
    try:
        location = geolocator.geocode(name, timeout=5)
        return location
    except GeocoderTimedOut as e:
        print("Error: geocode failed on input %s with message %s" % (e.msg))
Mciver answered 3/11, 2017 at 8:54 Comment(2)
This answer did not work in 2021 with Windows 10 answer from Brad Ahrens worked for me.Natterjack
Sure, I did this question 4 years ago. Please, update the question and add the solution for your environment!Mciver
O
2

this simple peace of code worked for me (Windows):

python -m pip install python-certifi-win32

If this doesn't work try this:

pip install  --trusted-host pypi.org --trusted-host pypi.python.org --trusted-host files.pythonhosted.org python-certifi-win32

Ref: https://levelup.gitconnected.com/fixing-your-ssl-verify-errors-in-python-71c2201db4b2

Oldham answered 11/1, 2022 at 9:47 Comment(0)
S
0

Hello this one worked for me because I am getting error with geopy.geocoders Nomimatim.

from geopy.geocoders import ArcGIS
from geopy.exc import GeocoderTimedOut

def getLocation(name):
    geolocator = ArcGIS(scheme='http')
    try:
        location = geolocator.geocode(name, timeout=5)
        return location
    except GeocoderTimedOut as e:
        print("Error: geocode failed on input %s with message %s" % (e.msg))
Shark answered 28/12, 2018 at 23:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.