[Bug 251562] security/py-certifi: SSLError 'certificate verify failed' despite correct looking /etc/ssl/cert.pem
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 10 Jan 2026 23:17:38 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=251562
--- Comment #7 from Michael Osipov <michaelo@FreeBSD.org> ---
(In reply to Benjamin Takacs from comment #6)
No, buth they are fundamentally different. While certifi reinvents the wheel
(no pun intended), truststore truly instructs OpenSSL to use its default
truststore. Certifi is capable of using anything outside of the Mozilla bundle.
[1] was the successor to certifi and the predecessor to truststore.
You need to do:
> import truststore
> truststore.inject_into_ssl()
but in applications only, not in libraries! Ideally the dependent ports you
have mentioned would solve it upstream, not downstream. Stuff like py-sphinx is
a good candidate because it is CLI.
Affected ports:
> $ grep -r --include=Makefile /py-certifi .
> ./astro/py-skyfield/Makefile: ${PYTHON_PKGNAMEPREFIX}certifi>0:security/py-certifi@${PY_FLAVOR}
> ./astro/py-skyfield/Makefile: ${PYTHON_PKGNAMEPREFIX}certifi>0:security/py-certifi@${PY_FLAVOR}\
> ./comms/py-pynitrokey/Makefile: ${PYTHON_PKGNAMEPREFIX}certifi>=14.5.14,:security/py-certifi@${PY_FLAVOR} \
> ./comms/py-pynitrokey/Makefile: ${PYTHON_PKGNAMEPREFIX}certifi>=14.5.14,:security/py-certifi@${PY_FLAVOR} \
> ./databases/py-snowflake-connector-python/Makefile: ${PYTHON_PKGNAMEPREFIX}certifi>=2017.4.17:security/py-certifi@${PY_FLAVOR} \
> ./devel/oci-cli/Makefile: ${PYTHON_PKGNAMEPREFIX}certifi>0:security/py-certifi@${PY_FLAVOR} \
> ./devel/py-cibuildwheel/Makefile: ${PYTHON_PKGNAMEPREFIX}certifi>0:security/py-certifi@${PY_FLAVOR} \
> ./devel/py-geventhttpclient/Makefile: ${PYTHON_PKGNAMEPREFIX}certifi>=0:security/py-certifi@${PY_FLAVOR} \
> ./devel/py-gptscript/Makefile:RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}certifi>=2024.2.2:security/py-certifi@${PY_FLAVOR} \
> ./devel/py-minio/Makefile:RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}certifi>=0:security/py-certifi@${PY_FLAVOR} \
> ./devel/py-oci/Makefile:RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}certifi>0:security/py-certifi@${PY_FLAVOR} \
> ./devel/py-pdm/Makefile: ${PYTHON_PKGNAMEPREFIX}certifi>=2024.8.30:security/py-certifi@${PY_FLAVOR} \
> ./devel/py-pipenv/Makefile:RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}certifi>=0:security/py-certifi@${PY_FLAVOR} \
> ./devel/py-sentry-sdk/Makefile:RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}certifi>=0:security/py-certifi@${PY_FLAVOR} \
> ./devel/py-tiamat/Makefile:RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}certifi>=0:security/py-certifi@${PY_FLAVOR} \
> ./finance/electrum/Makefile: ${PYTHON_PKGNAMEPREFIX}certifi>0:security/py-certifi@${PY_FLAVOR} \
> ./finance/py-ccxt/Makefile:RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}certifi>=2018.1.18:security/py-certifi@${PY_FLAVOR} \
> ./finance/py-valinvest/Makefile:RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}certifi>=2022.12.7:security/py-certifi@${PY_FLAVOR}
> ./graphics/py-fiona/Makefile: ${PYTHON_PKGNAMEPREFIX}certifi>0:security/py-certifi@${PY_FLAVOR} \
> ./graphics/py-pyogrio/Makefile:RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}certifi>=0:security/py-certifi@${PY_FLAVOR} \
> ./graphics/py-pyproj/Makefile:RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}certifi>=0:security/py-certifi@${PY_FLAVOR}
> ./graphics/py-rasterio/Makefile: ${PYTHON_PKGNAMEPREFIX}certifi>=0:security/py-certifi@${PY_FLAVOR} \
> ./math/py-matplotlib/Makefile: ${PYTHON_PKGNAMEPREFIX}certifi>=0.10:security/py-certifi@${PY_FLAVOR} \
> ./math/py-matplotlib/Makefile: ${PYTHON_PKGNAMEPREFIX}certifi>=0.10:security/py-certifi@${PY_FLAVOR} \
> ./misc/py-google-genai/Makefile: ${PYTHON_PKGNAMEPREFIX}certifi>=2024.8.30:security/py-certifi@${PY_FLAVOR} \
> ./misc/py-napari/Makefile: ${PYTHON_PKGNAMEPREFIX}certifi>=2018.1.18:security/py-certifi@${PY_FLAVOR} \
> ./multimedia/streamlink/Makefile:RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}certifi>0:security/py-certifi@${PY_FLAVOR}\
> ./multimedia/syncplay/Makefile: ${PYTHON_PKGNAMEPREFIX}certifi>=0:security/py-certifi@${PY_FLAVOR} \
> ./net-mgmt/py-msrest/Makefile: ${PYTHON_PKGNAMEPREFIX}certifi>=2017.4.17:security/py-certifi@${PY_FLAVOR} \
> ./net-p2p/py-pulsar-client/Makefile:RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}certifi>0:security/py-certifi@${PY_FLAVOR}
> ./net/py-twitter-tools/Makefile:RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}certifi>0:security/py-certifi@${PY_FLAVOR}
> ./net/py-urllib31/Makefile:SSL_RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}certifi>=0:security/py-certifi@${PY_FLAVOR} \
> ./security/py-cryptography/Makefile: ${PYTHON_PKGNAMEPREFIX}certifi>=2024:security/py-certifi@${PY_FLAVOR} \
> ./security/py-nethsm/Makefile:RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}certifi>=14.5.14,:security/py-certifi@${PY_FLAVOR} \
> ./security/py-plaso/Makefile: ${PYTHON_PKGNAMEPREFIX}certifi>=0:security/py-certifi@${PY_FLAVOR} \
> ./security/py-signxml/Makefile:RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}certifi>=2023.11.17:security/py-certifi@${PY_FLAVOR} \
> ./sysutils/py-kubernetes/Makefile:RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}certifi>=14.05.14:security/py-certifi@${PY_FLAVOR} \
> ./textproc/py-elastic-transport/Makefile:RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}certifi>=0:security/py-certifi@${PY_FLAVOR} \
> ./textproc/py-elasticsearch-curator/Makefile: ${PYTHON_PKGNAMEPREFIX}certifi>=2018.10.15:security/py-certifi@${PY_FLAVOR} \
> ./textproc/py-elasticsearch7/Makefile:RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}certifi>=0:security/py-certifi@${PY_FLAVOR} \
> ./textproc/py-evtx2splunk/Makefile:RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}certifi>0:security/py-certifi@${PY_FLAVOR} \
> ./textproc/py-jq/Makefile:TEST_DEPENDS= ${PYTHON_PKGNAMEPREFIX}certifi>=0:security/py-certifi@${PY_FLAVOR} \
> ./textproc/py-opensearch-py/Makefile:RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}certifi>=0:security/py-certifi@${PY_FLAVOR} \
> ./www/buku/Makefile: ${PYTHON_PKGNAMEPREFIX}certifi>=0:security/py-certifi@${PY_FLAVOR} \
> ./www/firedm/Makefile: ${PYTHON_PKGNAMEPREFIX}certifi>0:security/py-certifi@${PY_FLAVOR} \
> ./www/py-aioquic/Makefile:RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}certifi>=0:security/py-certifi@${PY_FLAVOR} \
> ./www/py-calibreweb/Makefile: ${PYTHON_PKGNAMEPREFIX}certifi>=0:security/py-certifi@${PY_FLAVOR} \
> ./www/py-httpcore/Makefile:RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}certifi>=0:security/py-certifi@${PY_FLAVOR} \
> ./www/py-httpx/Makefile: ${PYTHON_PKGNAMEPREFIX}certifi>=0:security/py-certifi@${PY_FLAVOR} \
> ./www/py-nicegui/Makefile: ${PYTHON_PKGNAMEPREFIX}certifi>=0:security/py-certifi@${PY_FLAVOR} \
> ./www/py-primp/Makefile:TEST_DEPENDS= ${PYTHON_PKGNAMEPREFIX}certifi>0:security/py-certifi@${PY_FLAVOR} \
> ./www/py-puppetboard/Makefile:RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}certifi>=2025.4.26:security/py-certifi@${PY_FLAVOR} \
> ./www/py-requests/Makefile:RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}certifi>=2017.4.17:security/py-certifi@${PY_FLAVOR} \
> ./www/py-searxng-devel/Makefile: ${PYTHON_PKGNAMEPREFIX}certifi>=0:security/py-certifi@${PY_FLAVOR} \
> ./www/py-selenium-wire/Makefile: ${PYTHON_PKGNAMEPREFIX}certifi>=2019.9.1:security/py-certifi@${PY_FLAVOR} \
> ./www/py-selenium/Makefile: ${PYTHON_PKGNAMEPREFIX}certifi>=2021.10.8:security/py-certifi@${PY_FLAVOR}
> ./www/py-sherlock-project/Makefile:RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}certifi>=2019.6.16:security/py-certifi@${PY_FLAVOR} \
> ./www/py-yt-dlp/Makefile: ${PYTHON_PKGNAMEPREFIX}certifi>0:security/py-certifi@${PY_FLAVOR} \
> ./www/yt-dlp/Makefile: ${PYTHON_PKGNAMEPREFIX}certifi>0:security/py-certifi@${PY_FLAVOR} \
Some of them I do use, some are really weird because why does matplotlib
require it at build time.
Test:
> osipovmi@deblndw011x:/tmp/test-venv/create
> $ source bin/activate
> osipovmi@deblndw011x:/tmp/test-venv/create
> $ pip list
> Package Version
> ---------- -------
> pip 23.0.1
> setuptools 65.5.0
>
> [notice] A new release of pip is available: 23.0.1 -> 25.3
> [notice] To update, run: pip install --upgrade pip
> osipovmi@deblndw011x:/tmp/test-venv/create
> $ pip install requests
> Collecting requests
> Downloading requests-2.32.5-py3-none-any.whl (64 kB)
> ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 64.7/64.7 kB 669.9 kB/s eta 0:00:00
> Collecting urllib3<3,>=1.21.1
> Downloading urllib3-2.6.3-py3-none-any.whl (131 kB)
> ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 131.6/131.6 kB 690.6 kB/s eta 0:00:00
> Collecting charset_normalizer<4,>=2
> Downloading charset_normalizer-3.4.4-py3-none-any.whl (53 kB)
> ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 53.4/53.4 kB 1.5 MB/s eta 0:00:00
> Collecting idna<4,>=2.5
> Downloading idna-3.11-py3-none-any.whl (71 kB)
> ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 71.0/71.0 kB 1.9 MB/s eta 0:00:00
> Collecting certifi>=2017.4.17
> Downloading certifi-2026.1.4-py3-none-any.whl (152 kB)
> ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 152.9/152.9 kB 1.4 MB/s eta 0:00:00
> Installing collected packages: urllib3, idna, charset_normalizer, certifi, requests
> Successfully installed certifi-2026.1.4 charset_normalizer-3.4.4 idna-3.11 requests-2.32.5 urllib3-2.6.3
>
> [notice] A new release of pip is available: 23.0.1 -> 25.3
> [notice] To update, run: pip install --upgrade pip
> osipovmi@deblndw011x:/tmp/test-venv/create
> $ pip list
> Package Version
> ------------------ --------
> certifi 2026.1.4
> charset-normalizer 3.4.4
> idna 3.11
> pip 23.0.1
> requests 2.32.5
> setuptools 65.5.0
> urllib3 2.6.3
>
> [notice] A new release of pip is available: 23.0.1 -> 25.3
> [notice] To update, run: pip install --upgrade pip
> osipovmi@deblndw011x:/tmp/test-venv/create
> $ python -c 'import requests; print(requests.get("https://dw-eng-rsc.innomotics.net"))'
> Traceback (most recent call last):
> File "/tmp/test-venv/create/lib/python3.10/site-packages/urllib3/connectionpool.py", line 464, in _make_request
> self._validate_conn(conn)
> File "/tmp/test-venv/create/lib/python3.10/site-packages/urllib3/connectionpool.py", line 1093, in _validate_conn
> conn.connect()
> File "/tmp/test-venv/create/lib/python3.10/site-packages/urllib3/connection.py", line 796, in connect
> sock_and_verified = _ssl_wrap_socket_and_match_hostname(
> File "/tmp/test-venv/create/lib/python3.10/site-packages/urllib3/connection.py", line 975, in _ssl_wrap_socket_and_match_hostname
> ssl_sock = ssl_wrap_socket(
> File "/tmp/test-venv/create/lib/python3.10/site-packages/urllib3/util/ssl_.py", line 483, in ssl_wrap_socket
> ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls, server_hostname)
> File "/tmp/test-venv/create/lib/python3.10/site-packages/urllib3/util/ssl_.py", line 527, in _ssl_wrap_socket_impl
> return ssl_context.wrap_socket(sock, server_hostname=server_hostname)
> File "/usr/local/lib/python3.10/ssl.py", line 513, in wrap_socket
> return self.sslsocket_class._create(
> File "/usr/local/lib/python3.10/ssl.py", line 1104, in _create
> self.do_handshake()
> File "/usr/local/lib/python3.10/ssl.py", line 1375, in do_handshake
> self._sslobj.do_handshake()
> ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1017)
>
> During handling of the above exception, another exception occurred:
>
> Traceback (most recent call last):
> File "/tmp/test-venv/create/lib/python3.10/site-packages/urllib3/connectionpool.py", line 787, in urlopen
> response = self._make_request(
> File "/tmp/test-venv/create/lib/python3.10/site-packages/urllib3/connectionpool.py", line 488, in _make_request
> raise new_e
> urllib3.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1017)
>
> The above exception was the direct cause of the following exception:
>
> Traceback (most recent call last):
> File "/tmp/test-venv/create/lib/python3.10/site-packages/requests/adapters.py", line 644, in send
> resp = conn.urlopen(
> File "/tmp/test-venv/create/lib/python3.10/site-packages/urllib3/connectionpool.py", line 841, in urlopen
> retries = retries.increment(
> File "/tmp/test-venv/create/lib/python3.10/site-packages/urllib3/util/retry.py", line 535, in increment
> raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type]
> urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='dw-eng-rsc.innomotics.net', port=443): Max retries exceeded with url: / (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1017)')))
>
> During handling of the above exception, another exception occurred:
>
> Traceback (most recent call last):
> File "<string>", line 1, in <module>
> File "/tmp/test-venv/create/lib/python3.10/site-packages/requests/api.py", line 73, in get
> return request("get", url, params=params, **kwargs)
> File "/tmp/test-venv/create/lib/python3.10/site-packages/requests/api.py", line 59, in request
> return session.request(method=method, url=url, **kwargs)
> File "/tmp/test-venv/create/lib/python3.10/site-packages/requests/sessions.py", line 589, in request
> resp = self.send(prep, **send_kwargs)
> File "/tmp/test-venv/create/lib/python3.10/site-packages/requests/sessions.py", line 703, in send
> r = adapter.send(request, **kwargs)
> File "/tmp/test-venv/create/lib/python3.10/site-packages/requests/adapters.py", line 675, in send
> raise SSLError(e, request=request)
> requests.exceptions.SSLError: HTTPSConnectionPool(host='dw-eng-rsc.innomotics.net', port=443): Max retries exceeded with url: / (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1017)')))
> osipovmi@deblndw011x:/tmp/test-venv/create
> $ pip install truststore
> Collecting truststore
> Downloading truststore-0.10.4-py3-none-any.whl (18 kB)
> Installing collected packages: truststore
> Successfully installed truststore-0.10.4
>
> [notice] A new release of pip is available: 23.0.1 -> 25.3
> [notice] To update, run: pip install --upgrade pip
> osipovmi@deblndw011x:/tmp/test-venv/create
> $ pip list
> Package Version
> ------------------ --------
> certifi 2026.1.4
> charset-normalizer 3.4.4
> idna 3.11
> pip 23.0.1
> requests 2.32.5
> setuptools 65.5.0
> truststore 0.10.4
> urllib3 2.6.3
>
> [notice] A new release of pip is available: 23.0.1 -> 25.3
> [notice] To update, run: pip install --upgrade pip
> osipovmi@deblndw011x:/tmp/test-venv/create
> $ python -c 'import truststore; import requests; truststore.inject_into_ssl(); print(requests.get("https://dw-eng-rsc.innomotics.net"))'
> <Response [200]>
>
[1] https://github.com/tiran/certifi-system-store
--
You are receiving this mail because:
You are the assignee for the bug.
You are on the CC list for the bug.