[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate in certificate chain

Greeting, I am trying to connect to the OpenAI api from python. but have failed. I have searched the openAI api documentations and openAI dev forums. My openAI version is 1.14.3. I cannot use lower version to use assistant model

import os
from openai import OpenAI
OPENAI_API_KEY = 'my-key'

os.environ['PYTHONHTTPSVERIFY'] = '0'
os.environ['REQUESTS_CA_BUNDLE'] = 'C:\MyProgram\python\certificate.crt'

client = OpenAI(api_key = OPENAI_API_KEY)

and I got the following error

File "C:\Users\Username\AppData\Local\Programs\Python\Python312\Lib\site-packages\httpx\_transports\default.py", line 86, in map_httpcore_exceptions
    raise mapped_exc(message) from exc
httpx.ConnectError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate in certificate chain (_ssl.c:1000)

and

File "C:\Users\Username\AppData\Local\Programs\Python\Python312\Lib\site-packages\httpcore\_exceptions.py", line 14, in map_exceptions
    raise to_exc(exc) from exc
httpcore.ConnectError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate in certificate chain (_ssl.c:1000)

I have tried the below solutions

  1. as shown above, I have downloaded certificate from https://api.openai.com/ manually and gave my cert to os. environ followed by hardkothari1988`s answer but not worked. I have set os.environ[‘PYTHONHTTPSVERIFY’] = ‘0’ to disable HTTPS verify but not worked either
os.environ['PYTHONHTTPSVERIFY'] = '0'
os.environ['REQUESTS_CA_BUNDLE'] = 'C:\MyProgram\python\certificate.crt'
  1. used pip install pip_system_certs to install certs in python itself. but not worked

  2. have used

import certifi
certifi.where()

not worked

  1. have tried

    1. Open api_requestor.py in a text editor. (site-packages/openai/api_requestor.py)
    2. Find the line: s = requests.Session()
    3. Add directly below: s.verify = False

but there was no api_requestory.py exists in current open api version.
Instead I have explored Python312\Lib\site-packages\httpx_transports\default.py
which makes error, and switched its verify flag but not worked

  1. set openai.verify_ssl_certs = false but not worked

and I have checked connection with open ai using Open Port Check Tool - Test Port Forwarding on Your Router
with openAI`s ip: 104.18.7.192 with 443 port it is opend

Yesterday I have used legacy openAI and worked well. In legacy version, there is no assistant model connection is provied so I have to use recent one. is anyone knows the solution?

I have the same problem. Most of the hacks are related to Python requests package and not httpx.Client. anyone else have this figured ?

I am experiencing the same error if I run my code locally with PyCharm however if I paste the same code into a Google Colab it works.

So, I’m using the OpenAI client in a container.

client= OpenAI(base_url=“https://blah.blah.com”, api_key=“sk-no-key-required”)

I get the SSL: CERTIFICATE_VERIFY_FAILED message when my software tries to establish the connection. When I use a curl from the command line in my container… it works. because my root certs ARE installed properly in my container, but urllib doesn’t want to use them.

There’s lots of examples our there on how to hand-jam root certs into urllib and create your own connection pool, but that doesn’t help me because I didn’t write the OpenAI module… so I don’t know how to tell the OpenAI module to use my connection pool. I have the public keys for my root certs, they’re sitting RIGHT there in my /etc/pki/ca-trust directory. I don’t understand why urllib doesn’t see them.

Maybe I’m being stupid because I’m thinking this doesn’t seem like a hard thing… but I can’t seem to figure it out.

Appreciate any help. Thanks!

Solved it. It wasn’t urllib to blame, it was httpx. I put the following into my environment variables in a wrapper before I ran my python and I’m in business.

export SSL_CERT_FILE=/etc/pki/ca-trust/extracted/pem/ca-bundle.pem
export REQUESTS_CA_BUNDLE=/etc/pki/ca-trust/extracted/pem/ca-bundle.pem

2 Likes

Hi, Could you elaborate a little bit more detailed?

If you want to use your own self-signed trusted root CAs, you have to tell the httpx module in python where to find them. It’s not enough to just have them loaded in the “default” location since it doesn’t use it.

Troubleshooting becomes confusing because the “curl” “wget” and the browsers (well except firefox) all use whatever certs you’ve loaded into your system cert manager. But, the python httpx module uses it’s own unless you set the environment variables above.

I just wrote a bash wrapper around my app that sets these variables and now it’s working.

This isn’t strictly an issue using the openai client to talk to openai.com… but it was an issue for me because I’m using the openai python client to talk to a llama.cpp server. Anyway… thought I’d share my experience maybe it will help somebody else along the way.

1 Like

I’v had the same error when accessing OpenAI API in PyCharm. But when executing the same code in the terminal of the same Linux machine, it works well with no connection error. After tracing the code, I finally found out the difference was due to different setting of environment variables related to SSL Certificate.
In the terminal, the environment variable SSL_CERT_DIR was set to /etc/ssl/certs, but in PyCharm environment, nothing was set so default (‘…/python3.8/site-packages/certifi/cacert.pem’ by certifi.where()) was used.

In more details,
httpx first tries to get SSL file or path from environments (SSL_CERT_FILE, SSL_CERT_PATH) as in the below code from httpx/_utils.py:

def get_ca_bundle_from_env() -> str | None:
    if "SSL_CERT_FILE" in os.environ:
        ssl_file = Path(os.environ["SSL_CERT_FILE"])
        if ssl_file.is_file():
            return str(ssl_file)
    if "SSL_CERT_DIR" in os.environ:
        ssl_path = Path(os.environ["SSL_CERT_DIR"])
        if ssl_path.is_dir():
            return str(ssl_path)
    return None

httpx also tries to get SSLContext object given in params, or default path as in the below code from httpx/_config.py:

    def load_ssl_context_verify(self) -> ssl.SSLContext:
        """
        Return an SSL context for verified connections.
        """
        if self.trust_env and self.verify is True:
            ca_bundle = get_ca_bundle_from_env()
            if ca_bundle is not None:
                self.verify = ca_bundle

        if isinstance(self.verify, ssl.SSLContext):
            # Allow passing in our own SSLContext object that's pre-configured.
            context = self.verify
            self._load_client_certs(context)
            return context
        elif isinstance(self.verify, bool):
            ca_bundle_path = self.DEFAULT_CA_BUNDLE_PATH
        elif Path(self.verify).exists():
            ca_bundle_path = Path(self.verify)
        else:
            raise IOError(
                "Could not find a suitable TLS CA certificate bundle, "
                "invalid path: {}".format(self.verify)
            )
        ....

In summary,
appropriate SSL certificate should be given in

  • the environment variable ‘SSL_CERT_FILE’
  • the environment variable ‘SSL_CERT_DIR’
  • the argument ‘verify’ as already-configured SSLContext object
  • the argument ‘verify’ as the SSL certificate file path (in string)
  • or default certificate file path of the used python package