ERROR 2026 (HY000): SSL connection error: <detail> is raised when the TLS/SSL handshake between the MySQL client and server cannot be completed. The error symbol is CR_SSL_CONNECTION_ERROR.
Impact
This is a client-side connection error, meaning the connection is rejected before any query is executed. No transaction is started, no SQL reaches the server, and the application receives a fatal connection failure. Because it occurs at the transport layer, the error appears before any ORM or query builder has a chance to act.
In application frameworks, this surfaces as an unhandled connection exception at startup or at the point where a connection pool is first populated. In Java (JDBC/Connector/J), it typically throws CommunicationsException wrapping an SSLHandshakeException. In Python (mysql-connector-python or PyMySQL), it raises mysql.connector.errors.InterfaceError or OperationalError with the underlying SSL detail appended to the message. In Node.js (mysql2), the connection emits an ECONNRESET or SSL_ERROR event.
Common Causes
Expired or not-yet-valid certificate — The server's TLS certificate has passed its
notAfterdate, or the client certificate is outside its validity window. MySQL validates certificate dates during the handshake.CA certificate mismatch — The client is configured to verify the server's certificate (
--ssl-verify-server-certorssl_verify_server_cert=1) but the CA bundle provided does not include the issuing CA for the server cert. This is common when using self-signed certs or private PKI.Hostname / CN mismatch — Certificate verification is enabled and the server certificate's CN or Subject Alternative Names (SANs) do not match the hostname used in the connection string.
Incompatible TLS protocol versions — The client requires TLS 1.2 but the server only offers TLS 1.3 (or vice versa), or one side has disabled a protocol version that the other side requires. MySQL 8.0.28+ defaults to
tls_version=TLSv1.2,TLSv1.3; TLS 1.0 and 1.1 are removed.Incompatible cipher suites — The client and server have no overlapping cipher suite in common, so the handshake cannot negotiate encryption parameters.
Client configured to require SSL but server has SSL disabled — The client connection uses
--ssl-mode=REQUIREDor the driver'sssl=true, but the server was started without SSL support (have_ssl = DISABLED).Corrupted or wrong-format key/certificate files — A PEM file was accidentally truncated, stored in DER format, or the private key does not match the certificate.
Troubleshooting and Resolution Steps
Check whether the server has SSL enabled:
SHOW VARIABLES LIKE 'have_ssl'; SHOW VARIABLES LIKE 'have_openssl';If the result is
DISABLED, the server was compiled or started without TLS support. Either restart with--ssl-ca,--ssl-cert, and--ssl-keypointing to valid files, or use a distribution that includes OpenSSL support.Inspect the server's TLS configuration:
SHOW VARIABLES LIKE 'tls_version'; SHOW VARIABLES LIKE 'ssl_%';Note the
ssl_ca,ssl_cert, andssl_keypaths. Verify the files exist and are readable by the MySQL process.Check certificate validity dates from the shell:
openssl x509 -in /var/lib/mysql/server-cert.pem -noout -datesIf
notAfteris in the past, regenerate the certificate or renew it via your CA. For self-signed certs, re-runmysql_ssl_rsa_setupor generate manually:mysql_ssl_rsa_setup --datadir=/var/lib/mysqlVerify the CA chain and hostname match:
openssl verify -CAfile /path/to/ca-cert.pem /path/to/server-cert.pem openssl x509 -in /path/to/server-cert.pem -noout -subject -ext subjectAltNameThe CN or a SAN entry must match the hostname your client uses. If you connect to
127.0.0.1but the cert only coverslocalhost(or the FQDN), either add a SAN or disable hostname verification on the client (--ssl-mode=VERIFY_CAinstead ofVERIFY_IDENTITY).Test the TLS handshake directly with openssl:
openssl s_client -connect host:3306 -starttls mysql -CAfile /path/to/ca-cert.pemThe output shows the negotiated protocol, cipher, and any certificate errors without involving the MySQL client.
Check and align TLS versions:
-- On the server, restrict or expand allowed versions: SET GLOBAL tls_version = 'TLSv1.2,TLSv1.3'; ALTER INSTANCE RELOAD TLS; -- applies without restart (MySQL 8.0+)On the client side, pass
--tls-version=TLSv1.2(CLI) or settls_versionsin your connector configuration.Temporarily skip certificate verification to isolate the issue:
mysql -h host -u user -p --ssl-mode=REQUIRED --ssl-ca='' 2>/dev/null # or mysql -h host -u user -p --ssl-mode=PREFERREDIf this succeeds, the problem is certificate-related rather than a protocol mismatch. Do not leave verification disabled in production.
Additional Information
- Error 2026 is a client-side error in the CR_ (Client Result) range. It is distinct from server-side SSL errors reported in the MySQL error log.
- The trailing detail in the message (e.g.,
SSL connection error: error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed) is the raw OpenSSL error string and usually pinpoints the exact cause. - In MySQL 8.0,
ALTER INSTANCE RELOAD TLSallows replacing certificates at runtime without a server restart. --ssl-modeacceptsDISABLED,PREFERRED,REQUIRED,VERIFY_CA, andVERIFY_IDENTITY. The default in MySQL 8.0 clients isPREFERRED; many cloud providers enforceREQUIREDorVERIFY_CA.- AWS RDS, Google Cloud SQL, and Azure Database for MySQL each ship their own CA bundles. Download the correct bundle from your cloud provider rather than using the system CA store.
- Related errors: CR_SSL_CONNECTION_ERROR (2026) is sometimes accompanied by server-side
ER_ACCESS_DENIED_ERROR (1045)if the user account requiresREQUIRE SSLand the connection falls back to plaintext.
Frequently Asked Questions
Why does MySQL 2026 happen only after a cert renewal?
After renewing a certificate, the new cert's CA chain or SANs sometimes differ from the old one. If the client was configured with a pinned CA (--ssl-ca) and the new cert was issued by a different intermediate CA, the trust chain breaks. Re-export and redistribute the new CA bundle to all clients and reload the TLS configuration on the server with ALTER INSTANCE RELOAD TLS.
Can I connect without SSL to work around this temporarily?
Yes, if the server allows non-SSL connections: use --ssl-mode=DISABLED in the CLI or set ssl=false in your driver. However, user accounts configured with REQUIRE SSL will still reject the connection with error 1045. For production databases that store sensitive data, bypassing SSL is not recommended.
Why does this error appear in Docker or CI environments?
Containerized MySQL setups often generate self-signed certificates at first startup, but automated clients running in a different container may use a system CA store that does not include those self-signed CAs. Either mount the generated ca-cert.pem into the client container, or configure the client with --ssl-mode=REQUIRED (without CA verification) if certificate identity validation is not needed in that environment.
How do I confirm the TLS handshake is working after a fix?
Connect with the mysql CLI and run:
\s
-- or
SHOW STATUS LIKE 'Ssl_cipher';
A non-empty Ssl_cipher value confirms that the current session is encrypted. SHOW SESSION STATUS LIKE 'Ssl_version' shows the negotiated protocol version.