requests does not use the defaults from ssl; it uses envvar REQUESTS_CA_BUNDLE or CURL_CA_BUNDLE if set and otherwise uses the (spunoff) certifi module which depending on how you installed requests&certifi which you didn't say and your environment which you didn't identify might use a system default (which might or might not be the same as the OpenSSL used in ssl) or might be its own copy of Mozilla. In the latter case it should include Digicert Global Root CA as needed for that site, because Firefox (also Mozilla) does.

Look at requests.certs.where() or python -m requests.certs

Mostly dupe
Python Requests - How to use system ca-certificates (debian/ubuntu)?
How to force requests use the certificates on my ubuntu system
Why python requests not use the system ssl cert by default?

Answer from dave_thompson_085 on Stack Overflow
🌐
GitHub
github.com › psf › requests › issues › 6660
REQUESTS_CA_BUNDLE and CURL_CA_BUNDLE environment variables get ignored when in a venv · Issue #6660 · psf/requests
March 13, 2024 - Requests supports the REQUESTS_CA_BUNDLE and CURL_CA_BUNDLE environment variables to override the certificate Expected Result Here's what's happening outside of the venv REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt python3 Pytho...
Author   FriederHannenheim
🌐
GitHub
github.com › psf › requests › issues › 1491
Installed certifi, set REQUESTS_CA_BUNDLE env var, still getting SSL error. · Issue #1491 · psf/requests
July 24, 2013 - I tried saving the certificate from the jenkins server and setting the REQUESTS_CA_BUNDLE environment variable to point to it, and still got the same error. I also tried installing certifi but it makes no difference. I know I could hack the jenkinsapi code but that is not satisfactory because all users of my code would have to do the same thing.
Author   hugh-dunne
Discussions

ssl - How to force requests use the certificates on my ubuntu system - Stack Overflow
And python -m requests.certs returns /usr/local/lib/python2.7/dist-packages/certifi/cacert.pem. How can I make requests to use the certs on the system. I'm working on dockerize sth, and would not like to see that verify=path-to-cert in my code. More on stackoverflow.com
🌐 stackoverflow.com
ssl - How can I use system CA certificates (Debian/Ubuntu) with Python's Requests? - Stack Overflow
Setting environmental variable REQUESTS_CA_BUNDLE works. However, it does not change crt path in certifi module. The answer implies that it does, but my test in python 3.7 and 3.8 shows otherwise. I recommand use os.getenv to check the path instead. More on stackoverflow.com
🌐 stackoverflow.com
CA-certs bundles and requests.certs.where - Improved documentation
I initially thought requests.certs.where (as well as certifi.where) returned the location of the cacert file actually being used, and I could use it to verify that the correct file was loaded. I am not the only one to make this mistake: ... More on github.com
🌐 github.com
2
November 1, 2023
Setting `REQUESTS_CA_BUNDLE` to directory causes exception
Describe the bug The requests library supports setting REQUESTS_CA_BUNDLE to either a single certificate file, or to a directory of files. It appears that botocore assumes this value will only be a file and raises an exception if it is s... More on github.com
🌐 github.com
7
August 2, 2022
🌐
Google Groups
groups.google.com › g › django-users › c › nxDIv_qLjmM
How to configure client side SSL trusted CA certificate ?
February 7, 2017 - I've tried all those options, but none worked. It turned out that the init script in init.d for the server (written by a different party) is using "su -" to start a new login shell clearing all env vars. Whatever that was set in the init script and /etc/default/... were thrown away. I had to export the REQUESTS_CA_BUNDLE in "-c".
🌐
Quantlane
quantlane.com › blog › ssl-lessons-learned-part-2
Quantlane - SSL Lessons learned: Part 2
August 9, 2020 - We found out that requests using its own pre-packaged SSL certificates can be disabled by using the environment variable REQUESTS_CA_BUNDLE. Although I would not recommend blindly disabling it everywhere. I think it is better for our CI as we take care only for system SSL certificates from now on.
Top answer
1 of 8
269

From an answer to Python Requests throwing SSLError:

To make Python's Requests use the system ca-certificates bundle, it needs to be told to use it over its own embedded bundle

export REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt

Requests embeds its bundles here, for reference:

/usr/local/lib/python2.7/site-packages/requests/cacert.pem
/usr/lib/python3/dist-packages/requests/cacert.pem

Or in newer versions, use an additional package to obtain certificates from: Certifi

To verify from which file certificates are loaded, you can try:

Python 3.8.5 (default, Jul 28 2020, 12:59:40)
>>> import certifi
>>> certifi.where()
'/etc/ssl/certs/ca-certificates.crt'
2 of 8
42

I struggled with this for a week or so recently. I finally found that the way to verify a self-signed, or privately signed, certificate in Python. You need to create your own certificate bundle file. No need to update obscure certificate bundles every time you update a library, or add anything to the system certificate store.

Start by running the openssl command that you ran before, but add -showcerts. openssl s_client -connect mysite.local:443 -showcerts This will give you a long output, and at the top you'll see the entire certificate chain. Usually, this means three certs, the website's certificate, the intermediate certificate, and the root certificate in that order. We need to put just the root and intermediate certificates into a next file in the opposite order.

Copy the last cert, the root certificate, to a new text file. Grab just the stuff between, and including:

-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----

Copy the middle cert (aka the intermediate certificate) to the new text file under the root cert. Again, grab the Begin and End Certificate lines and everything in between.

Save this text file to the directory where your Python script resides. My recommendation is to call it CertBundle.pem. (If you give it a different name, or put it somewhere else in your folder structure, make sure that the verify line reflects that.) Update your script to reference the new certificate bundle:

response = requests.post("https://www.example.com/", headers=headerContents, json=bodyContents, verify="CertBundle.pem")

And that's it. If you have only the root or only the intermediate certificate, then Python can't validate the entire certificate chain. But, if you include both of the certificates in the certificate bundle that you created, then Python can validate that the intermediate was signed by the root, and then when it accesses the website it can validate that the website's certificate was signed by the intermediate certificate.

edit: Fixed the file extension for the cert bundle. Also, fixed a couple of grammatical mistakes.

Find elsewhere
🌐
Requests
requests.readthedocs.io › en › latest › user › advanced
Advanced Usage — Requests 2.33.1 documentation
When certifi was not installed, this led to extremely out-of-date certificate bundles when using significantly older versions of Requests. For the sake of security we recommend upgrading certifi frequently! By default, when you make a request, the body of the response is downloaded immediately. You can override this behaviour and defer downloading the response body until you access the Response.content attribute with the stream parameter:
🌐
GitHub
github.com › psf › requests › issues › 6565
CA-certs bundles and requests.certs.where - Improved documentation · Issue #6565 · psf/requests
November 1, 2023 - $ REQUESTS_CA_BUNDLE=/home/jdoe/catest/my_cacert.pem python test.py os.environ.get("REQUESTS_CA_BUNDLE") -> '/home/jdoe/catest/my_cacert.pem' os.environ.get("CURL_CA_BUNDLE") -> None requests.cert.where()) -> '/home/jdoe/.local/lib/python3.10/site-packages/certifi/cacert.pem' certifi.where()) -> '/home/jdoe/.local/lib/python3.10/site-packages/certifi/cacert.pem' Currently requests.certs.where.__doc__ returns null. How about · returns the path of the CA-certs bundle that is included with the requests package, ie not necessarily the bundle actually being used.
Author   velle
🌐
GitHub
github.com › boto › botocore › issues › 2731
Setting `REQUESTS_CA_BUNDLE` to directory causes exception · Issue #2731 · boto/botocore
August 2, 2022 - REQUESTS_CA_BUNDLE=/usr/local/lib/python3.10/site-packages/certifi/cacert.pem aws s3 ls An error occurred (AccessDenied) when calling the ListBuckets operation: Access Denied · Please disregard the Access Denied error, that is expected. Unsuccessful execution with REQUESTS_CA_BUNDLE set to a directory: REQUESTS_CA_BUNDLE=/etc/ssl/certs/ aws s3 ls SSL validation failed for https://s3.us-east-2.amazonaws.com/ [Errno 21] Is a directory · One working solution I've found with some local experimentation is to modify _setup_ssl_cert to check whether a given path is a directory and set the connection parameters accordingly.
Author   sstoops
🌐
Python.org
discuss.python.org › python help
Can connect to URL with curl but not with requests (i.e. requests ignoring my CA bundle?) - Python Help - Discussions on Python.org
March 30, 2022 - (Cross-posting from python - can connect to URL with curl but not with requests (i.e. requests ignoring my CA bundle?) - Stack Overflow) I am able to connect to a certain URL with cURL, after I installed the corresponding SSL certificates: $ curl -vvvv $MY_URL # Fails $ sudo openssl x509 -inform pem -outform pem -in /tmp/custom-cert.pem -out /usr/local/share/ca-certificates/custom-cert.crt $ sudo update-ca-certificates $ curl -vvvv $MY_URL # OK However, requests (or httpx, or any other libr...
🌐
Stack Overflow
stackoverflow.com › questions › 58892964 › azureml-sdk-ignores-the-requests-ca-bundle-environment-variable
python - azureml-sdk ignores the REQUESTS_CA_BUNDLE environment variable - Stack Overflow
It works fine by manually append the server certificate to the file "cert_ca.pem" of the package certifi. As mentioned in the documentation of python-requests, this should also be possible by setting the environment variable "REQUESTS_CA_BUNDLE" to a specific file.
🌐
Stack Overflow
stackoverflow.com › questions › 34794958 › how-to-add-optional-ca-bundle-in-requests
python - How to add optional CA bundle in requests - Stack Overflow
This is 2016 and not 2008. UPDATE: I no longer need a work-around, the site in question fixed their crap. However an elegant solution would still be appreciated for curiosity. ... Add all your other (system) CAs to the bundle in /path/to/CA1_BUNDLE. ... @SteffenUllrich: That makes maintenance a lot more work since currently my distro manages the system CAs for me.
🌐
GitHub
github.com › astral-sh › uv › issues › 17853
REQUESTS_CA_BUNDLE not honored by UV · Issue #17853 · astral-sh/uv
February 4, 2026 - Summary When using requests() within UV, it uses the default cacert.pem from certifi. Even when I export REQUESTS_CA_BUNDLE to a private CA file. Tested it with local Python and it works fine. Here is a example snippet: $ REQUESTS_CA_BUN...
Author   cmdrrobin
🌐
GitHub
github.com › psf › requests › issues › 5921
requests should ignore REQUESTS_CA_BUNDLE when session.verify is False · Issue #5921 · psf/requests
September 1, 2021 - $> REQUESTS_CA_BUNDLE=invalid python -c 'import requests; session = requests.Session(); session.verify = False; session.get("https://expired.badssl.com")' ... OSError: Could not find a suitable TLS CA certificate bundle, invalid path: invalid
Author   brmzkw
🌐
GitHub
github.com › aws › aws-cli › issues › 3425
REQUESTS_CA_BUNDLE cannot be set to a directory · Issue #3425 · aws/aws-cli
July 3, 2018 - Therefore, I exported REQUESTS_CA_BUNDLE=/etc/ssl/certs to my global environment variables, so that all Python apps using requests can see my certs. With most apps, everything works just fine. However, this does not work for aws-cli.
Author   psliwka
🌐
GitHub
gist.github.com › mavaddat › 29bea8cbc54d14b5ca04aef6af0cfeca
Setting Python REQUESTS_CA_BUNDLE for Windows using all the available certificates on the machine. Answer to this Stackoverflow question: https://stackoverflow.com/questions/51925384/unable-to-get-local-issuer-certificate-when-using-requests-in-python · GitHub
Setting Python REQUESTS_CA_BUNDLE for Windows using all the available certificates on the machine. Answer to this Stackoverflow question: https://stackoverflow.com/questions/51925384/unable-to-get-local-issuer-certificate-when-using-requests-in-python - setPythonRequestsCaBundle.ps1
🌐
GitHub
github.com › kubernetes-client › python › issues › 1131
Configure SSL CA CERTIFICATE with REQUESTS_CA_BUNDLE env var before certifi · Issue #1131 · kubernetes-client/python
March 31, 2020 - # ca_certs if configuration.ssl_ca_cert: ca_certs = configuration.ssl_ca_cert else: # if not set certificate file, use Mozilla's root certificates. ca_certs = certifi.where() ... # ca_certs if configuration.ssl_ca_cert: ca_certs = configuration.ssl_ca_cert elif 'REQUESTS_CA_BUNDLE' in os.environ: ca_certs = environ.get('REQUESTS_CA_BUNDLE') else: # if not set certificate file, use Mozilla's root certificates.
Author   nirousseau
🌐
IncognitJoe
incognitjoe.github.io › adding-certs-to-requests.html
Adding custom CA certs to Requests with Certifi | IncognitJoe
December 24, 2016 - import certifi import requests try: print('Checking connection to Slack...') test = requests.get('https://api.slack.com') print('Connection to Slack OK.') except requests.exceptions.SSLError as err: print('SSL Error. Adding custom certs to Certifi store...') cafile = certifi.where() with open('certicate.pem', 'rb') as infile: customca = infile.read() with open(cafile, 'ab') as outfile: outfile.write(customca) print('That might have worked.') # Actual app logic here, hopefully without SSL issues.