ER_PUBLIC_KEY_RETRIEVAL_NOT_ALLOWED

MySQL 8.0 public key retrieval is not allowed — the real fix

This error appears when connecting to MySQL 8.0 over non-SSL with a password. The fix: add allowPublicKeyRetrieval=true to your connection string or client config. Here's why and how.

Yes, this error is annoying. Here's the fix.

You're trying to connect to MySQL 8.0 and it hits you with ER_PUBLIC_KEY_RETRIEVAL_NOT_ALLOWED. If you just want it to work, add allowPublicKeyRetrieval=true to your connection string or client option. That's it. The error will disappear.

// JDBC example
jdbc:mysql://localhost:3306/dbname?allowPublicKeyRetrieval=true&useSSL=false

// Python (mysql-connector-python)
import mysql.connector
conn = mysql.connector.connect(
    host='localhost',
    user='root',
    password='secret',
    allow_public_key_retrieval=True
)

// MySQL CLI (if you're using a wrapper that respects it)
mysql --ssl-mode=DISABLED --allow-public-key-retrieval -u root -p

For JDBC, you might also need useSSL=false unless you've set up SSL properly. For the CLI, remember the option is --allow-public-key-retrieval (with dashes), not the camelCase version.

Now, why does this even happen? Let's dig into the mess.

What's actually happening here is a security dance

MySQL 8.0 changed the default authentication plugin from mysql_native_password to caching_sha2_password. That new plugin is stricter about how passwords are sent over the wire. When you connect without SSL, the server can't safely send the password as plaintext. Instead, it uses RSA encryption with a public key. But the client has to fetch that public key from the server first. And by default, MySQL refuses to hand it out unless you explicitly say you're okay with it — that's what allowPublicKeyRetrieval=true signals.

The reason MySQL blocks it by default is a man-in-the-middle attack vector. If a malicious server intercepts your connection, it could give you its own public key, and you'd encrypt your password with that. The attacker then decrypts it and has your password. So MySQL says: "I won't send you the public key unless you explicitly ask for it, because you're taking on that risk."

Keep in mind: with SSL enabled, this whole issue vanishes because the password is encrypted over the SSL channel, and the public key doesn't need to be exchanged separately. That's why you'll see recommendations to just enable SSL — the right fix if you're in production.

Less common variations: when the same error shows up elsewhere

It's not just JDBC or Python. You'll see this error pop up in all sorts of places, and the root cause is always the same, but the fix looks different.

1. MySQL Workbench

Workbench gives you a checkbox during connection setup. Go to the connection settings, SSL tab, and check "Allow public key retrieval." Some versions hide it under "Advanced" — look for the option there. If you've already created the connection, edit it and save. No CLI needed.

2. PHP PDO

With PDO, you'd add the flag in the DSN options. It's not a separate DSN parameter, but a PDO option you set after constructing the DSN:

$pdo = new PDO(
    'mysql:host=localhost;dbname=test;charset=utf8mb4',
    'user',
    'password',
    [PDO::MYSQL_ATTR_SSL_KEY => null, PDO::MYSQL_ATTR_SSL_CERT => null]
);
// Actually, for PDO it's trickier — you may need to use the mysqlnd driver option
// or set MYSQL_ATTR_SSL_VERIFY_SERVER_CERT to false and add 'allowPublicKeyRetrieval' as a driver option
// PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false, PDO::MYSQL_ATTR_SSL_CA => null

Honestly, PHP is a mess here because the option isn't consistently exposed. The cleanest way is to use the MYSQL_ATTR_SSL_CA with a proper cert, or switch to a different auth plugin. Some people just create a new user with mysql_native_password to dodge the problem — more on that below.

3. Node.js (mysql2)

In mysql2, you add allowPublicKeyRetrieval: true to the connection options object. It's a simple property, and it works. Just don't forget it's camelCase in JS, not snake_case.

const connection = mysql.createConnection({
  host: 'localhost',
  user: 'root',
  password: 'secret',
  allowPublicKeyRetrieval: true
});

4. DBeaver / other GUI clients

Most modern GUIs have a checkbox under "Driver properties" or "Connection settings." If you can't find it, you can also add allowPublicKeyRetrieval=true as a custom JDBC URL parameter in the connection's advanced settings. Look for the "Edit Driver Settings" or "Connection URL" field.

Another angle: switch the user to mysql_native_password

If you're in a hurry and can't modify every client, you can change the user's authentication plugin back to the old one. This isn't the best long-term move — MySQL 8.0 defaults to caching_sha2_password for a reason, and future versions might drop mysql_native_password entirely. But for legacy apps that you can't update, it's a solid stopgap.

ALTER USER 'user'@'host' IDENTIFIED WITH mysql_native_password BY 'password';
FLUSH PRIVILEGES;

After that, the error goes away even without allowPublicKeyRetrieval, because the old plugin doesn't need the RSA dance. Just know you're trading security for compatibility.

Prevention: how to never see this again

The real fix is to use SSL whenever possible. If you're connecting over a trusted network (localhost, internal VPN), the risk of MITM is low, so enabling allowPublicKeyRetrieval is acceptable. But for any production connection that goes over the internet, set up SSL and forget about this error.

Practical steps:

  • If you control the server, generate a self-signed cert and configure MySQL to use it. Then in your client, set useSSL=true and point to the CA file.
  • If you're using a cloud provider (AWS RDS, Google Cloud SQL), they usually provide SSL endpoints. Use them.
  • If you're stuck with a legacy client that can't do SSL, create a dedicated user with mysql_native_password just for that app, and scope it to the least privileges it needs.

And if you're just prototyping locally, don't overthink it. Add allowPublicKeyRetrieval=true to your connection string and move on. You'll know when you need to harden things up.

Remember: this error is a feature, not a bug. It's MySQL forcing you to acknowledge a risk. Once you understand that, the fix makes total sense.
Related Errors in Database Errors
18456 SQL Server Error 18456: Login Failed for User 53300 PostgreSQL 'too many clients' error: real fixes that work Fix Query Execution Plan Invalidated Error in SQL Server 0X000010DA Fix ERROR_DATABASE_FULL 0X000010DA on SQL Server

Was this solution helpful?

EP
Erropedia Team
Tech Support Editors
The Erropedia editorial team researches and documents real-world tech errors from across Windows, Linux, macOS, networking, databases, cloud platforms, and more. Every solution is reviewed for accuracy and updated as software and systems evolve.