The error SSL connection unexpectedly closed from clickhouse-client, the HTTPS endpoint, or distributed queries usually means the client cannot validate the peer certificate because it is not loading any CA bundle. ClickHouse does not probe the system CA path on CentOS, Amazon Linux, RHEL, and several other distributions, so unless caConfig is set explicitly, OpenSSL aborts the TLS handshake. This article shows how to point both the client and server at the OS trust store so secure connections complete.
Why the error happens
OpenSSL ships defaults for the CA directory (/etc/ssl/certs on most Debian/Ubuntu builds), but ClickHouse links against its own OpenSSL build that does not inherit those defaults. On RHEL-family systems, the CA bundle lives at /etc/pki/tls/certs/ca-bundle.crt and the directory at /etc/pki/ca-trust/extracted/pem/. Without an explicit <caConfig> entry, the client validates against an empty trust set and the handshake terminates with SSL connection unexpectedly closed.
The same problem hits server-side code that opens outbound TLS connections, for example HTTPS dictionary sources and ZooKeeper over TLS.
Client-side fix
Drop a config snippet into /etc/clickhouse-client/conf.d/openssl-ca.xml:
<config>
<openSSL>
<client>
<caConfig>/etc/ssl/certs</caConfig>
</client>
</openSSL>
</config>
caConfig accepts either a directory of PEM files or a single bundle file. On RHEL-family systems use one of:
<caConfig>/etc/pki/tls/certs/ca-bundle.crt</caConfig>
<caConfig>/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem</caConfig>
Server-side fix
The server needs the same setting in two places: <server> controls how incoming HTTPS and secure native connections present and validate certificates, and <client> controls outbound TLS the server itself opens. Drop this into /etc/clickhouse-server/conf.d/openssl-ca.xml:
<config>
<openSSL>
<server>
<caConfig>/etc/ssl/certs</caConfig>
</server>
<client>
<caConfig>/etc/ssl/certs</caConfig>
</client>
</openSSL>
</config>
Reload the server with SYSTEM RELOAD CONFIG or restart clickhouse-server.
Verifying the fix
Test the client first:
clickhouse-client --secure -h your-host.example.com -q "SELECT 1"
For HTTPS, use curl with the same CA bundle ClickHouse uses to confirm the certificate chain itself is valid:
curl --cacert /etc/ssl/certs/ca-bundle.crt \
"https://your-host.example.com:8443/?query=SELECT%201"
If curl succeeds but ClickHouse still fails, the issue is the caConfig path, not the certificate.
Distribution-specific paths
| Distribution | Recommended caConfig |
|---|---|
| Debian / Ubuntu | /etc/ssl/certs |
| RHEL / CentOS / Rocky / Alma | /etc/pki/tls/certs/ca-bundle.crt |
| Amazon Linux 2 | /etc/pki/tls/certs/ca-bundle.crt |
| Amazon Linux 2023 | /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem |
| Alpine | /etc/ssl/certs/ca-certificates.crt |
Common Pitfalls
- Only configuring the client side on a node that also opens outbound TLS. HTTPS dictionaries and ZooKeeper TLS fail until you set
<client>inside<openSSL>on the server config too. - Pointing
caConfigat a directory that contains only symlinks generated byupdate-ca-trust extractwithout runningc_rehashfirst. OpenSSL needs hashed symlinks to look up CAs by subject hash. - Using a self-signed corporate CA without adding it to the system trust store. Either install the CA into the system bundle and run
update-ca-trust extract, or pointcaConfigat a PEM file you manage yourself. - Forgetting to restart
clickhouse-serverafter dropping the config file.SYSTEM RELOAD CONFIGis enough for most settings; restart if logs do not show the new CA path. - Mixing the secure native port (default 9440) with the plain port (9000) in your client command.
--secureis required for 9440.
Frequently Asked Questions
Q: I see Certificate verification: self signed certificate in certificate chain instead. Is that the same problem?
A: Different symptom, same area. The CA path is now loading, but the chain you are receiving includes an intermediate or root that is not in the bundle. Add the issuing CA to the file or directory referenced by caConfig.
Q: Does this also affect inter-server replication over TLS?
A: Yes. Replication uses the same OpenSSL config block. Configure both <server> and <client> on every node in the cluster.
Q: How do I disable verification entirely for testing?
A: Add <verificationMode>none</verificationMode> inside <client>. Do not use this in production; it disables peer authentication.
Q: What ports use SSL in ClickHouse?
A: 8443 for HTTPS, 9440 for the secure native protocol, and 9010 if you enable interserver HTTPS. All three rely on the same <openSSL> config block.
Q: Can I set caConfig via environment variable?
A: No. ClickHouse reads OpenSSL settings from XML only. Use a config snippet under conf.d/.