aiohttp.client_exceptions.ClientConnectorCertificateError: 无法连接到主机 example.com:443 ssl:True [SSLCertVerificationError: (1, '[SSL: CERTIFICATE_VERIFY_FAILED] 证书验证失败:无法获取本地颁发者证书')]
aiohttp.client_exceptions.ClientConnectorCertificateError: Cannot connect to host example.com:443 ssl:True [SSLCertVerificationError: (1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate')]
ID: python/aiohttp-client-connector-ssl-certificate-error
版本兼容性
| 版本 | 状态 | 引入 | 弃用 | 备注 |
|---|---|---|---|---|
| 3.8 | active | — | — | — |
| 3.9 | active | — | — | — |
| 3.10 | active | — | — | — |
| 3.11 | active | — | — | — |
| 3.12 | active | — | — | — |
根因分析
TLS 握手失败,因为客户端信任库中没有签发服务器证书的 CA。常见于使用 python.org 安装包的 macOS,或缺少 ca-certificates 的容器。
English
The TLS handshake failed because the client's trust store does not contain the CA that signed the server certificate. Common on macOS with python.org installers or in containers missing ca-certificates.
解决方案
-
92% 成功率
# macOS python.org '/Applications/Python 3.x/Install Certificates.command' # Debian/Ubuntu apt-get install -y ca-certificates && update-ca-certificates # pip pip install --upgrade certifi
-
88% 成功率
import ssl, certifi ctx = ssl.create_default_context(cafile=certifi.where()) conn = aiohttp.TCPConnector(ssl=ctx) async with aiohttp.ClientSession(connector=conn) as s: ... -
85% 成功率
import ssl, truststore truststore.inject_into_ssl() # then aiohttp uses the OS trust store automatically
无效尝试
常见但无效的做法:
-
40% 失败
Disables verification and exposes the app to MITM; also not accepted by all aiohttp versions in the same way.
-
85% 失败
Affects urllib, not aiohttp/ssl; the SSL context still verifies.
-
50% 失败
Same security problem as ssl=False, and does not fix the trust-store gap for other hosts.