Unable to get local issuer certificate when using requests in python

PythonPython Requests

Python Problem Overview


here is my code

import requests;
url='that website';
headers={
  'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
  'Accept-Language':'zh-CN,zh;q=0.9,en;q=0.8,ja;q=0.7',
  'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
};
r = requests.get(url,headers=headers);
print(r);
print(r.status_code);

then it ran into this:

> requests.exceptions.SSLError: > > HTTPSConnectionPool(host='www.xxxxxx.com', port=44 3): > > Max retries exceeded with url: xxxxxxxx (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] > > certificate verify failed: unable to get local issuer certificate > (_ssl.c:1045)')))

what should i do?

Python Solutions


Solution 1 - Python

It's not recommended to use verify = False in your organization's environments. This is essentially disabling SSL verification.

Sometimes, when you are behind a company proxy, it replaces the certificate chain with the ones of Proxy. Adding the certificates in cacert.pem used by certifi should solve the issue. I had similar issue. Here is what I did, to resolve the issue -

  1. Find the path where cacert.pem is located -

> Install certifi, if you don't have. Command: pip install certifi

import certifi
certifi.where()
C:\\Users\\[UserID]\\AppData\\Local\\Programs\\Python\\Python37-32\\lib\\site-packages\\certifi\\cacert.pem

2. Open the URL on a browser. Download the chain of certificates from the URL and save as Base64 encoded .cer files.

  1. Now open the cacert.pem in a notepad and just add every downloaded certificate contents (---Begin Certificate--- *** ---End Certificate---) at the end.

Solution 2 - Python

If you have already tried to update the CA(root) Certificate using pip:

pip install --upgrade certifi

or have already downloaded the newest version of cacert.pem from https://curl.haxx.se/docs/caextract.html and replaced the old one in {Python_Installation_Location}\\lib\\site-packages\\certifi\\cacert.pem but it still does not work, then your client is probably missing the Intermediate Certificate in the trust chain.

Most browsers can automatically download the Intermediate Certificate using the URL in "Authority Info Access" section in the Certificate, but Python, Java, and openssl s_client cannot. They rely on the server proactively sending them the intermediate certificate.

Authority Infomation Access

If you speak Chinese you can read this awesome blog: https://www.cnblogs.com/sslwork/p/5986985.html and use this tool to check if the intermediate certificate is sent by / installed on the server or not: https://www.myssl.cn/tools/check-server-cert.html

If you do not, you can check this article: https://www.ssl.com/how-to/install-intermediate-certificates-avoid-ssl-tls-not-trusted/

We can also use openssl in Linux to cross-check this issue:

openssl s_client -connect yourwebsite:443

openssl: unable to get local issuer certificate The error message is even the same -- "unable to get local issuer certificate". I doubt that "local" here actually means "intermediate".

My current solution for this problem is like @Indranil's suggestion (https://stackoverflow.com/a/57466119/4522434): Export the Intermediate Certificate in browser using base64 X.509 CER format; then use Notepad++ to open it and copy the content into the end of cacert.pem in {Python_Installation_Location}\\lib\\site-packages\\certifi\\cacert.pem

Solution 3 - Python

If you're using macOS, search for "Install Certificates.command" file (it is usually in Macintosh HD > Applications > your_python_dir).

You can also find it with "command" + "break space" and paste "Install Certificates.command" in the field.

If you used brew to install python, your solution is there: https://stackoverflow.com/questions/44649449/brew-installation-of-python-3-6-1-ssl-certificate-verify-failed-certificate/44649450#44649450

Solution 4 - Python

Answers pointing to certifi are a good start and in this case there could be an additional step needed if on Windows.

pip install python-certifi-win32

The above package would patch the installation to include certificates from the local store without needing to manage store files manually. The patch was suggested to certifi but declined as "the purpose of certifi is not to be a cross-platform module to access the system certificate store." [https://github.com/certifi/python-certifi/pull/54#issuecomment-288085993]

The issue with local certificates traces to Python TLS/SSL and Windows Schannel. There is an open issue at Python [https://bugs.python.org/issue36011] and PEP that did not lead to a solution [https://www.python.org/dev/peps/pep-0543/#resolution]

Solution 5 - Python

I had the same problem. I was able to make requests against my server via the browser, but using python requests, I was getting the error mentioned above. Requests and certifi were both fully up to date; the problem ended up being my server's configuration.

The problem was that I had only installed the intermediate cert instead of the full cert chain.

In my case, following this article, I simply ran cat my-domain.crt my-domain.ca-bundle > my-domain.crt-combined and installed the crt-combined file on my server (via heroku's app settings interface) instead of the crt file.

Solution 6 - Python

You can also set REQUESTS_CA_BUNDLE env variable to force requests library to use your cert, that solved my issue.

Solution 7 - Python

This should solve your problem

This is because the url is a https site instead of http. So it requires ssl verification using certificates. If you are working in your firms workstation, internal use sites will be accessible through the browser managed by your organization. The organization will have setup the certificates.

Atleast these certificates are needed

  • ROOT CA certificate
  • Intermediate CA certificate
  • Website ( domain ) certificate

The browsers will have these certificates configured, but python will not. So you need to do some manual work to get it working.

As Indranil suggests, using verify=False is not recommended. So download all the certificates as mentioned in the above link and follow the steps.

Solution 8 - Python

In macOS just open Macintosh HD

Now Select Application Then Select Python folder ( Python3.6, Python3.7 Whatever You are using just select this folder )

Then, double click on Install Certificates.command. Now your error should be solved.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestioninnocentDrifterView Question on Stackoverflow
Solution 1 - PythonIndranilView Answer on Stackoverflow
Solution 2 - PythonJing HeView Answer on Stackoverflow
Solution 3 - PythonQuentinView Answer on Stackoverflow
Solution 4 - PythonSamuli PView Answer on Stackoverflow
Solution 5 - PythonjstaabView Answer on Stackoverflow
Solution 6 - PythonthegreydView Answer on Stackoverflow
Solution 7 - PythonNarayan BhatView Answer on Stackoverflow
Solution 8 - PythonHusain SuksarView Answer on Stackoverflow