eBook – Guide Spring Cloud – NPI EA (cat=Spring Cloud)
announcement - icon

Let's get started with a Microservice Architecture with Spring Cloud:

>> Join Pro and download the eBook

eBook – Mockito – NPI EA (tag = Mockito)
announcement - icon

Mocking is an essential part of unit testing, and the Mockito library makes it easy to write clean and intuitive unit tests for your Java code.

Get started with mocking and improve your application tests using our Mockito guide:

Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Reactive – NPI EA (cat=Reactive)
announcement - icon

Spring 5 added support for reactive programming with the Spring WebFlux module, which has been improved upon ever since. Get started with the Reactor project basics and reactive programming in Spring Boot:

>> Join Pro and download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Jackson – NPI EA (cat=Jackson)
announcement - icon

Do JSON right with Jackson

Download the E-book

eBook – HTTP Client – NPI EA (cat=Http Client-Side)
announcement - icon

Get the most out of the Apache HTTP Client

Download the E-book

eBook – Maven – NPI EA (cat = Maven)
announcement - icon

Get Started with Apache Maven:

Download the E-book

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

eBook – RwS – NPI EA (cat=Spring MVC)
announcement - icon

Building a REST API with Spring?

Download the E-book

Course – LS – NPI EA (cat=Jackson)
announcement - icon

Get started with Spring and Spring Boot, through the Learn Spring course:

>> LEARN SPRING
Course – RWSB – NPI EA (cat=REST)
announcement - icon

Explore Spring Boot 3 and Spring 6 in-depth through building a full REST API with the framework:

>> The New “REST With Spring Boot”

Course – LSS – NPI EA (cat=Spring Security)
announcement - icon

Yes, Spring Security can be complex, from the more advanced functionality within the Core to the deep OAuth support in the framework.

I built the security material as two full courses - Core and OAuth, to get practical with these more complex scenarios. We explore when and how to use each feature and code through it on the backing project.

You can explore the course here:

>> Learn Spring Security

Course – LSD – NPI EA (tag=Spring Data JPA)
announcement - icon

Spring Data JPA is a great way to handle the complexity of JPA with the powerful simplicity of Spring Boot.

Get started with Spring Data JPA through the guided reference course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (cat=Spring Boot)
announcement - icon

Refactor Java code safely — and automatically — with OpenRewrite.

Refactoring big codebases by hand is slow, risky, and easy to put off. That’s where OpenRewrite comes in. The open-source framework for large-scale, automated code transformations helps teams modernize safely and consistently.

Each month, the creators and maintainers of OpenRewrite at Moderne run live, hands-on training sessions — one for newcomers and one for experienced users. You’ll see how recipes work, how to apply them across projects, and how to modernize code with confidence.

Join the next session, bring your questions, and learn how to automate the kind of work that usually eats your sprint time.

Course – LJB – NPI EA (cat = Core Java)
announcement - icon

Code your way through and build up a solid, practical foundation of Java:

>> Learn Java Basics

Partner – LambdaTest – NPI EA (cat= Testing)
announcement - icon

Distributed systems often come with complex challenges such as service-to-service communication, state management, asynchronous messaging, security, and more.

Dapr (Distributed Application Runtime) provides a set of APIs and building blocks to address these challenges, abstracting away infrastructure so we can focus on business logic.

In this tutorial, we'll focus on Dapr's pub/sub API for message brokering. Using its Spring Boot integration, we'll simplify the creation of a loosely coupled, portable, and easily testable pub/sub messaging system:

>> Flexible Pub/Sub Messaging With Spring Boot and Dapr

1. Overview

While connecting a Java application to a MySQL 8 database, we may see a common exception:

Public Key Retrieval is not allowed

The message above doesn’t indicate a legacy bug. Instead, it’s a security safeguard by modern MySQL and MySQL Connector/J. It usually occurs during authentication when the JDBC driver can’t safely retrieve the MySQL server’s RSA public key.

In this tutorial, we’ll see different aspects related to the Public Key Retrieval is not allowed message:

  • when and why the error occurs
  • how to reproduce it on a modern MySQL setup
  • which fixes are available for the error

Let’s explore each of the above points.

2. When and Why the Error Occurs

MySQL uses caching_sha2_password as its new default authentication plugin for versions 8.0.4 and above. Critically, this plugin is more secure than its older counterparts.

When a client connects without SSL, the new authentication method requires password exchange using an RSA public key. This key is used to encrypt the password during exchange. For security reasons, MySQL Connector/J doesn’t allow automatic public key retrieval unless we explicitly configure it.

Generally, the error occurs when some of the conditions are true:

  • authentication uses caching_sha2_password
  • SSL is off or not available
  • public key retrieval isn’t explicitly allowed

As a result, the driver blocks the authentication process and throws the Public Key Retrieval is not allowed exception.

3. Reproducing the Error

Let’s try to reproduce the error in a local machine environment.

3.1. Test Setup

For this setup, we’re using two machines. On one machine, we have a Java installation. The other has a MySQL server.

Let’s call them A and B:

  • Machine A: MySQL 8 server with the IP 192.168.29.116
  • Machine B: Java client with the IP 192.168.29.21

After that, we configure the MySQL server.

3.2. MySQL Server Configuration

Let’s ensure MySQL listens on all interfaces.

For this, we edit the MySQL config file on machine A:

$ sudo cat /etc/mysql/mysql.conf.d/mysqld.cnf
...
bind-address = 0.0.0.0
...

Afterward, we restart MySQL:

$ sudo systemctl restart mysql

Now, everything should be in place.

3.3. Sample Database

To perform the setup, we create a database, mydb, and a user, testuser:

mysql> CREATE DATABASE mydb;
mysql> CREATE USER 'testuser'@'%'IDENTIFIED BY 'testpass';
mysql> GRANT ALL PRIVILEGES ON mydb.* TO 'testuser'@'%';
FLUSH PRIVILEGES;

The new user now has all the privileges on the database mydb. Moreover, the authentication uses the default MySQL 8 authentication plugin:

mysql > SELECT user, host, plugin FROM mysql.user WHERE user='testuser';

The plugin must be of type caching_sha2_password.

3.4. Triggering the Error with Java Test Code

Let’s try to trigger the error on machine B.

For this, we try to connect to a MySQL 8 instance with a standard JDBC connection string.

Specifically, we attempt a connection without SSL or specific RSA configurations:

import java.sql.Connection;
import java.sql.DriverManager;

public class TestConnection {
    public static void main(String[] args) throws Exception {
        String url = "jdbc:mysql://192.168.29.116:3306/mydb"+"?useSSL=false"+"&allowPublicKeyRetrieval=false";
        Connection conn = DriverManager.getConnection(
            url, "testuser", "testpass"
        );
        System.out.println("Connected successfully");
        conn.close();
    }
}

In the above example, testuser uses caching_sha2_password. Also, we explicitly disabled SSL (useSSL=false). The driver attempts to fetch the public key. However, it fails due to the default security policy and throws an exception.

When we run the above code, we can see the expected error:

com.mysql.cj.exceptions.InvalidConnectionAttributeException:
Public Key Retrieval is not allowed

As a result, we can verify that the lab setup is working as expected.

4. Fixes for the Error

From the setup we already have, we can deduce several points:

  • the exception doesn’t indicate wrong credentials
  • the authentication method requires RSA encryption
  • the driver refuses to fetch the public key automatically

So, even if the credentials are correct, the authentication method isn’t compatible.

There are several fixes for the error:

  • allowing public key retrieval (development mode only)
  • enabling SSL (secure way)
  • changing authentication plugin (last resort)

However, the choice to use a fix depends on the environment.

5. Allow Public Key Retrieval (Development Only)

One of the quick fixes for this error is to explicitly enable the public key retrieval.

We can do this by adding the allowPublicKeyRetrieval=true string to the connection URL:

"jdbc:mysql://192.168.29.116:3306/mydb"+"?useSSL=false"+"&allowPublicKeyRetrieval=true";

Now, the driver can fetch the RSA public key from the server.

However, this method should only be used for local testing. Critically, for a production environment, it weakens security when used without SSL.

6.  SSL Setup With Certificate Verification

If we configure SSL, we should get a more secure and permanent fix. Let’s see how to properly set up SSL on the MySQL server.

6.1. Enabling SSL on MySQL Server

First, we create a directory for MySQL SSL files:

$ sudo mkdir -p /etc/mysql/ssl

The above directory stores all certificates and private keys used by MySQL.

Next, we move to the new directory:

$ cd /etc/mysql/ssl

All files are now saved here, which helps protect sensitive keys.

MySQL needs a Certificate Authority (CA) to verify server certificates.

Let’s generate a CA private key:

$ sudo sh -c 'openssl genrsa 2048 > ca-key.pem'

The ca-key.pem is a private key and acts as the root of trust.

Next, we create a self-signed CA certificate using ca-key.pem:

$ sudo openssl req -new -x509 -nodes -days 3650 -key ca-key.pem -out ca.pem

In this case, the self-signed certificate ca.pem identifies the CA. Later, we also use it to sign the MySQL server certificate.

Next, we need two more keys:

  • server-key.pem: private key for the server
  • server-req.pem: key for certificate signing request (CSR)

Let’s create both of these keys:

$ sudo openssl req -newkey rsa:2048 -days 3650 -nodes \
-keyout server-key.pem -out server-req.pem \
-subj "/C=US/ST=CL/L=NewYork/CN=192.168.29.116"

Now, we can sign the server certificate using the CA:

$ sudo openssl x509 -req -in server-req.pem -days 3650 \
-CA ca.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem

Finally, we get a trusted server certificate, server-cert.pem. Clients can use the CA certificate to verify it.

Let’s secure the SSL keys:

$ sudo chmod 600 *.pem
$ sudo chown mysql:mysql *.pem

This way, only MySQL can access them.

6.2. Configure MySQL to Use SSL

After getting the certificates, we configure MySQL to use them. For this, we add the SSL key paths under the [mysqld] section of the MySQL configuration file.

Let’s open the mysqld.cnf file and make the changes:

$ sudo cat /etc/mysql/mysql.conf.d/mysqld.cnf
...
ssl-ca = /etc/mysql/ssl/ca.pem
ssl-cert = /etc/mysql/ssl/server-cert.pem
ssl-key = /etc/mysql/ssl/server-key.pem
...

To make the changes work, we restart MySQL:

$ sudo systemctl restart mysql

Let’s verify if SSL is active by checking the current SSL configuration inside MySQL:

mysql > SHOW VARIABLES LIKE '%ssl%';

Similarly, we can check the MySQL runtime status:

mysql > SHOW GLOBAL STATUS LIKE 'Ssl_%';

If we see have_ssl = YES and SSL files in the output, this means MySQL is running with SSL.

6.3. Copying the Server Certificate to the Client

For the Java client to work with the MySQL server over SSL, both sides need to trust each other. For this, we use the CA certificate.

So, we copy ca.pem from the server to the Java client machine. Specifically, let’s copy it to /tmp via scp:

$ sudo scp /etc/mysql/ssl/ca.pem [email protected]:/tmp/ca.pem

The file should go under /tmp on the Java client.

6.4. Create and Verify Java Truststore on Client

Java uses a truststore to validate SSL certificates. With a custom truststore, we can avoid modifying the system-wide JVM configuration.

Let’s create a new truststore and import the CA certificate, ca.pem, to it:

$ keytool -import -alias mysqlCA -keystore /tmp/mysql-truststore.jks -file /tmp/ca.pem \
-storepass changeit -noprompt

Thus, JVM can now trust the MySQL server during SSL handshakes.

Let’s verify the truststore:

$ keytool -list -v -keystore /tmp/mysql-truststore.jks -storepass changeit

The output lists the certificate alias, type, and CA details.
So, we can now use the Java truststore for SSL connections to MySQL.

6.5. Java Code With SSL

Once the truststore is ready, we update the Java code to use SSL:

System.setProperty("javax.net.ssl.trustStore", "/tmp/mysql-truststore.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");

The properties point the JVM to the trusted certificates.

Finally, we update the JDBC connection URL:

String url = "jdbc:mysql://192.168.29.116:3306/mydb"+"?useSSL=true"+"&sslMode=VERIFY_CA"+"&allowPublicKeyRetrieval=true";

Each of the above parameters has a specific purpose:

  • useSSL=true: turns on SSL
  • sslMode=VERIFY_CA: checks the server certificate against the CA
  • allowPublicKeyRetrieval=true: allows secure retrieval of the server public key when required

Finally, when we run the Java code, there should be no Public Retrieval error.

8. Changing the Authentication Plugin

We can also support older clients, where caching_sha2_password isn’t used. In this case, we switch the user to the older mysql_native_password authentication plugin.

For this, we use the ALTER command on the MySQL prompt:

mysql > ALTER USER 'testuser'@'%' IDENTIFIED WITH mysql_native_password BY 'testpass';
mysql > FLUSH PRIVILEGES;

As a result, we don’t need the RSA key exchange. However, this is a less secure way as it relies on an older authentication plugin.

9. Conclusion

In this article, we saw causes for the Public Key Retrieval is not allowed error and how to fix it.

Overall, using SSL to fix such errors should be considered the best option since it provides a more secure authentication method.

Baeldung Pro – NPI EA (cat = Baeldung)
announcement - icon

Baeldung Pro comes with both absolutely No-Ads as well as finally with Dark Mode, for a clean learning experience:

>> Explore a clean Baeldung

Once the early-adopter seats are all used, the price will go up and stay at $33/year.

eBook – HTTP Client – NPI EA (cat=HTTP Client-Side)
announcement - icon

The Apache HTTP Client is a very robust library, suitable for both simple and advanced use cases when testing HTTP endpoints. Check out our guide covering basic request and response handling, as well as security, cookies, timeouts, and more:

>> Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

Course – LS – NPI EA (cat=REST)

announcement - icon

Get started with Spring Boot and with core Spring, through the Learn Spring course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (tag=Refactoring)
announcement - icon

Modern Java teams move fast — but codebases don’t always keep up. Frameworks change, dependencies drift, and tech debt builds until it starts to drag on delivery. OpenRewrite was built to fix that: an open-source refactoring engine that automates repetitive code changes while keeping developer intent intact.

The monthly training series, led by the creators and maintainers of OpenRewrite at Moderne, walks through real-world migrations and modernization patterns. Whether you’re new to recipes or ready to write your own, you’ll learn practical ways to refactor safely and at scale.

If you’ve ever wished refactoring felt as natural — and as fast — as writing code, this is a good place to start.

Course – LSS – NPI (cat=Security/Spring Security)
announcement - icon

I just announced the new Learn Spring Security course, including the full material focused on the new OAuth2 stack in Spring Security:

>> CHECK OUT THE COURSE

Course – LS – NPI (cat=Java)
announcement - icon

Get started with Spring Boot and with core Spring, through the Learn Spring course:

>> CHECK OUT THE COURSE

eBook Jackson – NPI EA – 3 (cat = Jackson)