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

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

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']}

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:

  • https://github.com/geopy/geopy/issues/124
  • Mongodb SSL connection failing when using SSL certificate issued by Let's encrypt suddenly even though the certificate is not expired
  • https://blog.devgenius.io/rhel-centos-7-fix-for-lets-encrypt-change-8af2de587fe4

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

yum upgrade ca-certificates