Python “CERTIFICATE_VERIFY_FAILED” on macOS: why it happens and the right fix

The website’s certificate is usually fine. The problem is that this copy of Python can’t find a list of trusted certificate authorities to check it against. The python.org installer for macOS doesn’t use the Mac’s Keychain and ships without that list until you run one small script.

The error

urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED]
certificate verify failed: unable to get local issuer certificate (_ssl.c:1000)>

Python uses its own copy of OpenSSL. OpenSSL looks for trusted root certificates in a file and a folder it was built to expect. The python.org macOS installer leaves those empty and puts a helper script, Install Certificates.command, in /Applications/Python 3.x/. Until it runs, every HTTPS connection made with the standard library fails, even to sites that work perfectly in your browser.

Why requests works but urllib doesn’t

The requests library uses the certifi package’s certificate list directly, so it doesn’t care what OpenSSL finds. urllib, http.client, asyncio, smtplib and tools built on them (some pip plugins, nltk.download(), torchvision dataset downloads, yt-dlp in some setups) use the default context and fail. aiohttp and httpx vary by version.

Fixes, in order

Your setupFix
Python from python.orgRun Install Certificates.command once per Python version (Finder: Applications, Python 3.x, double-click it)
Can’t find the script, or a virtual environmentpip install --upgrade certifi then export SSL_CERT_FILE="$(python3 -m certifi)" in your shell profile
Homebrew, pyenv or conda PythonUsually fine. If not: brew reinstall ca-certificates openssl@3, or rebuild the pyenv version after it; for conda, conda update ca-certificates certifi
Company network that inspects HTTPS (Zscaler, Netskope and similar)Get the company root certificate as a .pem, append it to a copy of the certifi bundle and point SSL_CERT_FILE and REQUESTS_CA_BUNDLE at that copy
You’d rather trust what the Mac trustsPython 3.10+: pip install truststore, then import truststore; truststore.inject_into_ssl() at the top of your program uses the Keychain

Check what Python is using

python3 -c "import ssl; print(ssl.get_default_verify_paths())"
python3 -c "import ssl, urllib.request; urllib.request.urlopen('https://example.com'); print('ok')"
python3 -m certifi        # path of the certifi bundle

If cafile points at a file that doesn’t exist, that’s the whole problem.

What not to do

ssl._create_unverified_context(), verify=False and PYTHONHTTPSVERIFY=0 make the error go away by accepting any certificate at all, including one from someone sitting on the same café Wi-Fi. Fine for a throwaway test against your own laptop; never in code that ships or handles passwords and tokens.

Related errors

The same message on Linux, in Node or in git usually means a missing intermediate certificate on the server or a proxy: see unable to get local issuer certificate. A real expired certificate is a different fix: certificate has expired. And wrong version number means you spoke HTTPS to a plain HTTP port: SSL wrong version number. Want to peek inside a PEM block someone sent you? Paste it into What is this?.

Questions

How do I fix CERTIFICATE_VERIFY_FAILED in Python on a Mac?

If Python came from python.org, run Install Certificates.command in /Applications/Python 3.x/. Otherwise install certifi and set SSL_CERT_FILE to the path printed by python3 -m certifi.

Why does requests work but urllib fails with CERTIFICATE_VERIFY_FAILED?

requests uses the certifi certificate bundle directly, while urllib uses OpenSSL's default locations, which the python.org macOS installer leaves empty until Install Certificates.command runs.

Do I need to run Install Certificates.command again?

Yes, once for each new Python version you install from python.org, because each has its own OpenSSL folder.

Is it OK to disable SSL verification to fix it?

Only for a quick local test. Turning verification off accepts any certificate, so anyone on the network could read or change the traffic.

Published .

Try it

Related guides

Newest guides