MySQL Public Key Retrieval Is Not Allowed
This Connector/J error appears when the active authentication path reaches a point where the client would need the server RSA public key but Connector/J is not allowed to retrieve it. This commonly involves caching_sha2_password or sha256_password on a non-TLS path; with caching_sha2_password, a cached fast-auth path can behave differently from a full authentication exchange. Do not start with the common internet recipe allowPublicKeyRetrieval=true&useSSL=false. First choose the intended secure transport. If TLS is intentionally disabled and full authentication needs RSA password exchange, use an approved key path.
caching_sha2_password or sha256_password, commonly with MySQL 8+.The error appears during authentication before your query runs.A GUI/framework may be constructing the JDBC URL for you, so the effective Connector/J properties matter more than the settings screen.sslMode=VERIFY_IDENTITY when you need both CA validation and hostname identity verification.REQUIRED requires an encrypted TLS connection, but it does not validate the server CA chain or hostname. Do not treat REQUIRED as certificate verification. Use VERIFY_CA or, preferably when hostname identity matters, VERIFY_IDENTITY.serverRSAPublicKeyFile or explicit allowPublicKeyRetrieval=true. Understand which key you trust before enabling retrieval.sslMode; secure connections do not need RSA password exchange for this authentication path.Find the effective Connector/J connection properties before adding anything. Connector/J 8.0.13+ uses sslMode; legacy useSSL, requireSSL, and verifyServerCertificate are deprecated mappings.
Confirm this is MySQL Connector/J and record its version.
DISABLED, PREFERRED, REQUIRED, VERIFY_CA, or VERIFY_IDENTITY?
Does the account use caching_sha2_password / sha256_password?
Verify: reproduce with the same JDBC driver and effective URL/properties as the failing application. Do not assume a successful MySQL CLI login proves the Java path is configured the same way.
Why this error exists
MySQL's caching_sha2_password can complete through a cached fast-auth path, but when full authentication is required the password exchange must be protected. Over TLS, the secure connection supplies that protection. On a non-TLS path, full authentication can use the server RSA public key. Connector/J does not permit the extra server-public-key retrieval round trip by default: allowPublicKeyRetrieval defaults to false. This is why behavior can appear intermittent after server restart, cache state changes, account/password changes, or movement to another server even when the JDBC URL is unchanged.
That is why simply changing the password or database permissions often does nothing—the failure is about the authentication transport, not SQL privileges.
Verify: force a fresh connection through the real application path rather than relying on an already-open pool connection. If verified TLS consistently removes the public-key retrieval error even when full authentication is required, the non-TLS RSA-retrieval branch is no longer needed.
Fix #1 — preferred remote/production path: use verified TLS
For remote or production connections, configure Connector/J to use TLS and validate the server identity. sslMode=VERIFY_CA verifies the certificate chain; sslMode=VERIFY_IDENTITY also verifies that the host name matches the server certificate. Connector/J can use a configured truststore or, depending on configuration, the Java system truststore.
jdbc:mysql://db.example.internal:3306/app?sslMode=VERIFY_IDENTITYIf the server uses a private/self-signed CA, configure the appropriate trusted CA through Java/Connector/J truststore settings rather than disabling certificate verification.
Verify: connect with VERIFY_IDENTITY (or your approved TLS policy) and confirm the application succeeds without allowPublicKeyRetrieval=true.
Fix #2 — non-TLS but controlled environment: pin the server RSA public key
If TLS is intentionally disabled and your security design permits RSA password exchange, Connector/J supports serverRSAPublicKeyFile. This supplies a client-side copy of the MySQL server's RSA public key used for password exchange instead of retrieving that key dynamically during authentication. It is not the TLS server certificate, a CA certificate, or a Java truststore.
serverRSAPublicKeyFile=/approved/path/mysql_server_public_key.pemVerify: with TLS intentionally disabled, create a fresh application connection that exercises the required authentication path and confirm it succeeds using the approved public-key file without dynamic key retrieval. Record which server/key the pin belongs to so failover or rotation does not silently change the trust assumption.
Fix #3 — when allowPublicKeyRetrieval=true is actually appropriate
allowPublicKeyRetrieval=true permits Connector/J to request the RSA public key from the server during authentication. It can solve this exact error when TLS is disabled, but the property exists behind a false default for a reason: you are allowing the connection to obtain the key it will use for password protection from the peer it has not authenticated through TLS.
jdbc:mysql://localhost:3306/app?sslMode=DISABLED&allowPublicKeyRetrieval=truesslMode=DISABLED into a remote production connection merely to clear the error.For production, prefer verified TLS. For a controlled non-TLS design where dynamic retrieval is accepted, document the trust assumption and network boundary. A pinned serverRSAPublicKeyFile avoids retrieving the key dynamically.
Verify: after enabling retrieval, confirm you are still in the intended network/security context. “Login works” alone does not prove the server identity is authenticated.
Fix #4 — stop mixing legacy useSSL with modern sslMode
Connector/J 8.0.13+ maps the deprecated legacy properties to sslMode. If sslMode is explicitly set, the legacy properties are ignored. This is why URLs copied from old answers can be misleading.
Verify: reduce the configuration to one intentional sslMode and confirm the effective application URL does not also depend on contradictory legacy properties.
Fix #5 — Spring, DBeaver, IDE, Docker, or CI still fails
Frameworks and tools can generate the JDBC URL, select a different Connector/J JAR, inject environment variables, reuse pooled connections, or route to another database node. Capture the actual driver version, effective properties and endpoint from the failing runtime. A local IDE test can succeed while a container uses another truststore, hostname, driver version, URL, server node, or authentication-cache state.
Verify: compare the effective JDBC URL/properties and Connector/J version between the working and failing environments, with passwords/tokens redacted.
Fix #6 — do not downgrade the account authentication plugin as the first fix
Connector/J supports caching_sha2_password. Changing the MySQL account to an older authentication plugin can hide the transport problem while weakening or complicating your authentication policy. Fix TLS/RSA exchange first unless your server/application compatibility requirements explicitly require another plugin.
Verify: keep the intended account authentication plugin and prove the application connects through the approved TLS or RSA path.
Final verification — prove more than “the login works”
Verify: remove any temporary test-only properties that are not part of the approved design and reconnect from the real application.
What not to do
allowPublicKeyRetrieval=true&useSSL=false from an old answer.Do not disable TLS on a remote production database just to clear this authentication error.Do not assume sslMode=REQUIRED verifies the server identity; it requires encryption but not CA/hostname validation.Do not use PREFERRED when policy requires encryption, because it can fall back to an unencrypted connection.Do not download an unknown RSA public key or CA certificate from the web.Do not downgrade caching_sha2_password as the first response to a transport/configuration problem.Do not publish JDBC URLs containing passwords, tokens, or private infrastructure details.Do not assume one successful cached authentication proves the full-authentication path is configured correctly; test a fresh connection through the real runtime.Do not replace a stale pinned server RSA key by enabling dynamic retrieval without validating whether the server key legitimately rotated.Do not assume a pooled connection reproduces authentication; an existing pool session may bypass the connection/authentication path you are trying to test.Do not keep diagnosing public-key retrieval once authentication advances and the error changes to TLS identity, access denied, database authorization or another stage.Still seeing “Public Key Retrieval is not allowed”?
If the next failure becomes a TLS certificate or hostname error, stay on the TLS branch and repair trust/identity. Do not retreat to sslMode=DISABLED merely because TLS validation exposed the next real issue.
Official references
Still stuck? Ask the community
Share the redacted Connector/J version, sslMode, authentication plugin, and whether the same host works through verified TLS.
Loading community discussion…
Comments could not load here. Open ErrorHarbor Discussions on GitHub →