Skip to main content

Fixed: "ERROR 3888 (HY000): Failed to set up SSL" with "Unable to get private key" in MySQL

· 4 min read
Jagdish Kumawat
Founder @ Dewiride

ERROR 3888: Failed to set up SSL with Unable to get private key means MySQL couldn't use the files you asked it to load. The good news is in the manual: a failed reload changes nothing, and the old certificate keeps running until you fix it.

What I Was Doing​

I was replacing the certificate on MySQL 9.7, and I'd put the wrong key in place of server-key.pem. Then, as root:

mysql>
ALTER INSTANCE RELOAD TLS;

What I Expected​

The new certificate in use, with no restart.

What I Got​

Output
ERROR 3888 (HY000): Failed to set up SSL because of the following SSL library error: Unable to get private key

The mysql client showing ERROR 3888: Failed to set up SSL because of the following SSL library error: Unable to get private key, after ALTER INSTANCE RELOAD TLS.

What I Checked​

Whether MySQL still had working TLS. It did. MySQL's manual says the reload "rolls back with an error and has no effect if the configuration values do not permit creation of the new TLS context. The previous context values continue to be used for new connections."

Whether the key and the certificate belong together. Their public keys must match, and these two commands print a fingerprint of each:

Terminal
openssl x509 -in server-cert.pem -noout -pubkey | openssl sha256
openssl pkey -in server-key.pem -pubout | openssl sha256

If the two lines differ, you have the wrong pair. Mine differed. A damaged key file gave me the same message, and so does a file MySQL can't read.

Why It Happens​

To set up TLS, MySQL loads the certificate and the key, and the TLS library refuses a key that doesn't belong to that certificate.

The Fix​

Put the matching key back. If you've made a new pair, make sure both files are from the same run, and readable by the mysql user. Then:

mysql>
ALTER INSTANCE RELOAD TLS;
Output
Query OK, 0 rows affected (0.001 sec)

Leave out NO ROLLBACK ON ERROR. With it, this failure turns TLS off rather than keeping the old certificate.

After the Fix​

mysql>
SHOW GLOBAL STATUS LIKE 'Ssl_server_not_after';
Output
+----------------------+--------------------------+
| Variable_name | Value |
+----------------------+--------------------------+
| Ssl_server_not_after | Feb 8 06:04:42 2029 GMT |
+----------------------+--------------------------+
1 row in set (0.000 sec)

The date is the new certificate's, so MySQL is using it.

A successful ALTER INSTANCE RELOAD TLS, and Ssl_server_not_after showing the new certificate's end date.

Common Mistakes​

MistakeWhat happensDo this instead
Restarting MySQL to "fix" itWith bad files, it starts without TLSFix the files first
Using NO ROLLBACK ON ERRORTLS goes off for new connectionsLeave it out
Mixing files from two runs of opensslThe key doesn't fitKeep each pair together

Troubleshooting​

SymptomLikely causeFix
The fingerprints match, and it still failsMySQL can't read the fileCheck its owner and permissions
It works, but clients get the old certificateThey're connections from before the reloadNew connections get the new one
ERROR 1227 (42000): Access denied; you need (at least one of) the CONNECTION_ADMIN privilege(s)Your account can't reloadUse an administrator

Conclusion​

ERROR 3888 from a reload means the new files don't work, and your old certificate is still running. Compare the fingerprints, fix the files, and reload.

Additional Resources​

Stay Updated

Subscribe to our newsletter for the latest tutorials, tech insights, and developer news.

By subscribing, you agree to our privacy policy. Unsubscribe at any time.