MySQL Error 2026 occurs when SSL/TLS handshake fails between client and server, typically due to protocol version mismatches, missing or expired certificates, or configuration mismatches. Fix it by verifying SSL is enabled on both sides, updating client libraries, and ensuring certificate files are accessible.
ERROR 2026 (HY000) is a generic SSL/TLS connection error that occurs when the MySQL client cannot establish a secure encrypted connection with the MySQL server. This error happens during the SSL handshake phase—before authentication is even attempted—indicating a problem with certificate validation, protocol negotiation, or SSL configuration. Unlike other MySQL errors that can pinpoint specific issues, ERROR 2026 is a catch-all error that requires investigation to identify the underlying cause. The error can be caused by certificate problems, protocol mismatches, permission issues, or disabled SSL on the server.
Connect to the MySQL server using a client that works (or locally on the server itself) and check if SSL is enabled:
SHOW VARIABLES LIKE 'have_%ssl%';
SHOW VARIABLES LIKE 'ssl_%';You should see output like:
have_openssl: YES
have_ssl: YES
ssl_ca: /path/to/ca.pem
ssl_cert: /path/to/server-cert.pem
ssl_key: /path/to/server-key.pemIf have_ssl or have_openssl is NO, MySQL was compiled without SSL support and needs to be rebuilt or reinstalled with OpenSSL libraries. Check the server's /etc/my.cnf or /etc/mysql/my.cnf to ensure the SSL paths are configured in the [mysqld] section.
MySQL 8.0.28 and later versions no longer support TLSv1.0 or TLSv1.1. If you are using an older client, it will fail with ERROR 2026. Check the server's configured minimum TLS version:
SHOW VARIABLES LIKE 'tls_version';If your client is outdated, upgrade it to a version that supports TLS 1.2 or 1.3:
- For mysql command line: Update MySQL client to version 8.0.28 or later
- For Python: Upgrade mysql-connector-python or PyMySQL to latest version
- For Node.js: Upgrade mysql2 package: npm install mysql2@latest
- For PHP: Ensure you have PHP 7.4+ with OpenSSL 1.1.1+ support
Alternatively, if you must use an older client, adjust the server configuration (not recommended for production):
[mysqld]
tls_version = TLSv1.2,TLSv1.3Then restart MySQL.
If you are using client-side certificates (common for remote connections and cloud databases), ensure all certificate files are present and readable:
ls -la /path/to/ca.pem
ls -la /path/to/client-cert.pem
ls -la /path/to/client-key.pemFor AWS RDS, download the certificate bundle:
wget https://truststore.pki.rds.amazonaws.com/global/global-bundle.pemThen connect using:
mysql -h your-rds-instance.region.rds.amazonaws.com -u admin -p --ssl-ca=global-bundle.pemFor Azure MySQL, download the DigiCertGlobalRootCA.crt file and use:
mysql -h your-instance.mysql.database.azure.com -u username@servername -p --ssl-ca=DigiCertGlobalRootCA.crt --ssl-mode=REQUIREDMake sure the current user has read permissions on these files. If running from a Docker container or different user, adjust permissions:
chmod 644 /path/to/ca.pemIf you are unable to resolve certificate verification issues and need to connect immediately, you can disable SSL verification (use with caution—only on trusted networks):
MySQL command line:
mysql --ssl-mode=DISABLED -h hostname -u user -pPython (mysql-connector):
import mysql.connector
config = {
'host': 'hostname',
'user': 'user',
'password': 'password',
'ssl_disabled': True
}
connection = mysql.connector.connect(**config)Node.js (mysql2):
const connection = mysql.createConnection({
host: 'hostname',
user: 'user',
password: 'password',
ssl: 'skip'
});WARNING: This disables encryption and leaves you vulnerable to man-in-the-middle attacks. Only use this temporarily for debugging.
Check that the certificate's Common Name (CN) or Subject Alternative Name (SAN) matches the hostname you are connecting to:
openssl x509 -in server-cert.pem -text -noout | grep -A1 "Subject Alternative Name"The connection hostname must match exactly. For example:
- If CN is mysql.example.com, connect to mysql.example.com, not 127.0.0.1 or the IP address
- If you are connecting via IP, the certificate must have the IP in the SAN field (unusual)
Also ensure the system clocks on both client and server are synchronized (within a few seconds):
date # On client
date # On server (or via SSH)Time drift of more than a few minutes can cause certificate validation failures. Sync using NTP:
ntpdate -u ntp.ubuntu.com # Or your NTP serverUse OpenSSL directly to test the SSL handshake and diagnose the exact issue:
openssl s_client -connect hostname:3306 -CAfile ca.pemLook for:
- Verify return code: 0 (ok) means the certificate is valid
- Verify return code: 20 (unable to get local issuer certificate) means the CA certificate is not recognized
- Verify return code: 27 (certificate not trusted) means the certificate is not signed by a trusted CA
- error:1425F102:SSL routines:ssl_choose_client_version:unsupported protocol means TLS version mismatch
If the handshake fails, the output will show the exact SSL error. Fix based on the error:
# Test with specific TLS version
openssl s_client -connect hostname:3306 -tls1_2 -CAfile ca.pem
# If certificate validation fails, test without verification
openssl s_client -connect hostname:3306 -CAfile ca.pem -partial_chainMySQL 8.0.28 introduced significant changes to SSL/TLS configuration. The removal of TLSv1.0 and TLSv1.1 support affects legacy applications that cannot be easily updated. If you have a large number of older clients, consider running MySQL 8.0.27 or earlier, or maintain a connection pool using a compatible version. For cloud databases (AWS RDS, Azure MySQL, Google Cloud SQL), always download and use the official certificate bundles provided by your cloud provider, as they change periodically. Self-signed certificates work for testing but are not recommended for production. If using a certificate authority, ensure renewal is automated to prevent expiration. Some MySQL client libraries have their own SSL configuration separate from the system OpenSSL. For example, PHP with mysqlnd uses bundled certificates, so PHP's OpenSSL version may differ from the system version. When using Docker containers, ensure the base image includes OpenSSL support and that certificate files are properly mounted and readable inside the container. Finally, ERROR 2026 with a detailed message like "SSL_ERROR_RX_RECORD_TOO_LONG" often indicates the client is trying to use SSL on a non-SSL port (default 3306 is SSL by default in recent MySQL versions, but some cloud databases use separate SSL ports).
EE_WRITE (3): Error writing file
How to fix "EE_WRITE (3): Error writing file" in MySQL
CR_PARAMS_NOT_BOUND (2031): No data supplied for parameters
How to fix "CR_PARAMS_NOT_BOUND (2031): No data supplied for parameters" in MySQL
CR_DNS_SRV_LOOKUP_FAILED (2070): DNS SRV lookup failed
How to fix "CR_DNS_SRV_LOOKUP_FAILED (2070): DNS SRV lookup failed" in MySQL
ERROR 1146: Table 'database.table' doesn't exist
How to fix "ERROR 1146: Table doesn't exist" in MySQL
ERROR 1040: Too many connections
How to fix "ERROR 1040: Too many connections" in MySQL