# MySQL ERROR 2026 SSL connection error: causes and fixes

> MySQL ERROR 2026 means the TLS handshake failed: CA verification, the auto-generated self-signed CA, a host name mismatch or no common TLS version.

Source: https://ssl.sh/errors/mysql-ssl-connection-error/
Last updated: 2026-11-10

**`ERROR 2026 (HY000): SSL connection error` means the MySQL client could not complete a TLS connection to the server.** The OpenSSL message after it tells you why: most often the server certificate could not be verified against the CA you supplied, the host name does not match, or client and server share no TLS version.

## Quick fix

The certificate's issuer tells you which CA file the client needs.

Look at the certificate the server presents (OpenSSL 1.1.1 or later), or paste it into the [certificate decoder](https://ssl.sh/tools/certificate-decoder/):

```bash
openssl s_client -starttls mysql -connect db.example.com:3306 </dev/null 2>/dev/null | openssl x509 -noout -subject -issuer -ext subjectAltName -enddate
```

Then connect with the matching CA:

```bash
mysql -h db.example.com -u app -p --ssl-mode=VERIFY_IDENTITY --ssl-ca=/etc/ssl/certs/db-ca.pem
```

- **Issuer is `MySQL_Server_..._Auto_Generated_CA_Certificate`:** the server uses its self-generated certificates; use its `ca.pem` with VERIFY_CA, or install a proper certificate for VERIFY_IDENTITY.
- **Issuer is your cloud provider's CA:** download that CA from the provider.

## Causes

### 1. Wrong or missing CA file

- **Confirm:** `certificate verify failed` with VERIFY_CA or VERIFY_IDENTITY; the issuer above is not the CA in `--ssl-ca`.
- **Fix:** use the root of the issuer. For managed databases (AWS RDS, Azure Database for MySQL, Google Cloud SQL, Alibaba Cloud RDS, Tencent Cloud), download the CA from the provider's documentation.

### 2. Auto-generated certificates and VERIFY_IDENTITY

MySQL Server creates a self-signed CA and server certificate in the data directory at first start if none are configured. Their subject names are generic, so host name verification always fails.

- **Confirm:** the subject reads `MySQL_Server_..._Auto_Generated_Server_Certificate`.
- **Fix:** issue a server certificate (from a private CA or a public CA) whose [SAN](https://ssl.sh/glossary/san/) contains the host name, and configure it:

```ini
[mysqld]
ssl_ca   = /etc/mysql/ssl/ca.pem
ssl_cert = /etc/mysql/ssl/server-cert.pem
ssl_key  = /etc/mysql/ssl/server-key.pem
require_secure_transport = ON
```

Since MySQL 8.0.16, `ALTER INSTANCE RELOAD TLS` applies new files without a restart.

### 3. No common TLS version

- **Confirm:** errors mention `unsupported protocol` or `no protocols available`; the server is an old 5.6/5.7 build compiled against an old TLS library.
- **Fix:** upgrade the server or set `tls_version=TLSv1.2,TLSv1.3` on a build that supports it.

### 4. Expired certificate

Auto-generated certificates are long-lived, but certificates you installed may expire.

- **Fix:** renew, replace the files and run `ALTER INSTANCE RELOAD TLS` (8.0.16+) or restart.

### 5. Server does not have TLS enabled

- **Confirm:** `SSL connection error: SSL is required but the server doesn't support it`.
- **Fix:** configure certificates on the server; check `SHOW VARIABLES LIKE '%ssl%';` and `\s` in the client for the active cipher.

## Fixes by environment

Every client needs the CA file that signed the server certificate and a host name that matches its [SAN](https://ssl.sh/glossary/san/). PostgreSQL uses the same model, see [sslmode=verify-full errors](https://ssl.sh/errors/postgres-sslmode-verify-full-error/).

**JDBC (Connector/J 8.x):** `jdbc:mysql://db.example.com:3306/app?sslMode=VERIFY_IDENTITY&trustCertificateKeyStoreUrl=file:/path/truststore.p12&trustCertificateKeyStorePassword=...`; import the CA with `keytool -importcert`.

**Python (PyMySQL / mysqlclient):** pass `ssl={"ca": "/path/db-ca.pem"}` and enable host name checking (`ssl_verify_identity=True` in PyMySQL).

**PHP (PDO):** `PDO::MYSQL_ATTR_SSL_CA => '/path/db-ca.pem'` and keep `PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT` enabled.

**MariaDB clients:** use `--ssl-ca` with `--ssl-verify-server-cert` for identity checks.

**Docker:** mount the CA into the application container and keep the database certificate files on a volume so they survive container recreation.

## Don't do this

- **Fall back to `--ssl-mode=REQUIRED` or `PREFERRED`** to silence verification errors. The connection is encrypted but the server is not authenticated.
- **Set `verifyServerCertificate=false` / `trustServerCertificate=true`** style options in drivers for production.
- **Expose 3306 to the internet** while debugging. Restrict access with security groups and keep TLS verification on.
