182

I try to connect MySql database with Java using connector 8.0.11. Everything seems to be ok but I have this exception:

Exception in thread "main" java.sql.SQLNonTransientConnectionException: Public Key Retrieval is not allowed

Stack Trace:

    Exception in thread "main" java.sql.SQLNonTransientConnectionException: Public Key Retrieval is not allowed at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:108) at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:95) at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) at 
 com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:862) at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:444) at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:230) at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:226) at com.mysql.cj.jdbc.MysqlDataSource.getConnection(MysqlDataSource.java:438) at com.mysql.cj.jdbc.MysqlDataSource.getConnection(MysqlDataSource.java:146) at com.mysql.cj.jdbc.MysqlDataSource.getConnection(MysqlDataSource.java:119) at ConnectionManager.getConnection(ConnectionManager.java:28) at Main.main(Main.java:8)

Connector Manager:

public class ConnectionManager {

    public static final String serverTimeZone = "UTC";
    public static final String serverName = "localhost";
    public static final String databaseName ="biblioteka";
    public static final int portNumber = 3306;
    public static final String user = "anyroot";
    public static final String password = "anyroot";

    public static Connection getConnection() throws SQLException {

        MysqlDataSource dataSource = new MysqlDataSource();

        dataSource.setUseSSL( false );
        dataSource.setServerTimezone( serverTimeZone );
        dataSource.setServerName( serverName );
        dataSource.setDatabaseName( databaseName );
        dataSource.setPortNumber( portNumber );
        dataSource.setUser( user );
        dataSource.setPassword( password );

        return dataSource.getConnection();
    }
}
Cœur
  • 32,421
  • 21
  • 173
  • 232
danny
  • 1,947
  • 2
  • 6
  • 8

17 Answers17

370

You should add client option to your mysql-connector allowPublicKeyRetrieval=true to allow the client to automatically request the public key from the server. Note that AllowPublicKeyRetrieval=True could allow a malicious proxy to perform a MITM attack to get the plaintext password, so it is False by default and must be explicitly enabled.

https://mysql-net.github.io/MySqlConnector/connection-options/

you could also try adding useSSL=false when you use it for testing/develop purposes

example:

jdbc:mysql://localhost:3306/db?allowPublicKeyRetrieval=true&useSSL=false
jtomaszk
  • 5,583
  • 2
  • 26
  • 39
  • 2
    Well, this worked for me but I am not sure how legit these options are from security perspective. – Priyank Thakkar Jun 20 '18 at 07:10
  • 39
    `useSSL=false&allowPublicKeyRetrieval=true` is what I needed only when I tried connecting from `docker_container1` to `docker_container2_mysql(where mysql is installed)` within my local host. While from my host machine to `docker_container2_mysql`, `useSSL=false` is enough. – prayagupd Jun 26 '18 at 05:02
  • 1
    allowPublicKeyRetrieval=true&useSSL=false , tank you it works – Martin Klestil Sep 02 '18 at 09:34
  • 2
    Can you explain why this is the case? – Capn Sparrow Sep 07 '18 at 04:45
  • Adding 'allowPublicKeyRetrieval=true' to my JDBC connection string solved my development system's issue after a Windows 10 update yesterday. Guess Microsoft plugged another hole, and the option should be used "for development only" in my view, where SSL is not turned on. – Alz Sep 15 '18 at 13:31
  • 2
    My problem is, it was working fine till yesterday. What could have changed overnight? – Sandeep Kumar Dec 31 '19 at 08:14
  • 2
    try removing useSSl=false from the url it worked for me – Saroj Kumar Sahoo May 02 '20 at 11:14
  • 1
    I was struggling making `dbeaver` connect to *dockerized* `mysql-8` server. `allowPublicKeyRetrieval=true` did the trick for me :+1: – ira Nov 24 '20 at 07:10
  • @SandeepKumar Same thing happened to me. Did you figure out why? And yes, I know a lot of time passed after you commented this, so I don't have high expectations :) – Stefan May 16 '21 at 15:01
103

For DBeaver users:

  1. Right click your connection, choose "Edit Connection"

  2. On the "Connection settings" screen (main screen) click on "Edit Driver Settings"

  3. Click on "Connection properties"

  4. Right click the "user properties" area and choose "Add new property"

  5. Add two properties: "useSSL" and "allowPublicKeyRetrieval"

  6. Set their values to "false" and "true" by double clicking on the "value" column

Javier Aviles
  • 2,956
  • 2
  • 18
  • 23
  • 6
    For me, modifying just the "allowPublicKeyRetrieval" field under "Driver Properties" from False to True did the trick. May I ask why add the "useSSL" property and then set it to False? (I too am using DBeaver) – Sandun Dec 15 '20 at 07:07
  • On Ubuntu 16.04, I had a heck of a time figuring out how to set the value because visually it did not show anything that looked like input was expected or being recorded. I had to double click the value column and trust that it was taking input before hitting enter or clicking out of it and only then did the value I typed in show up. – Stack Underflow Feb 25 '21 at 19:34
  • 1
    Is enough set both properties in the `Driver properties` section/tab – Manuel Jordan Mar 29 '21 at 21:38
  • Trying to connect to an out-of-the-box mysql install on a docker container. Doing this made it work so I can connect to the mysql db using dbeaver. – Halfstop May 20 '21 at 04:32
34

Use jdbc url as :

jdbc:mysql://localhost:3306/Database_dbName?allowPublicKeyRetrieval=true&useSSL=false;

PortNo: 3306 can be different in your configuation

susan097
  • 2,412
  • 17
  • 24
  • A small correction here. The connection property 'useSSL' acceptable values are: 'TRUE', 'FALSE', 'YES' or 'NO'. The value 'false;' is not acceptable. – bluelurker Mar 09 '19 at 18:26
22

When doing this from DBeaver I had to go to "Connection settings" -> "SSL" tab and then :

  • uncheck the "Verify server certificate"
  • check the "Allow public key retrival"

This is how it looks like. DBeaver configuration

Note that this is suitable for local development only.

michalk
  • 10,989
  • 2
  • 22
  • 46
17

Alternatively to the suggested answers you could try and use mysql_native_password authentication plugin instead of caching_sha2_password authentication plugin.

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_password_here'; 
Torsten Ojaperv
  • 843
  • 16
  • 21
4

I solve this issue using below configuration on spring boot framework

spring.datasource.url=jdbc:mysql://localhost:3306/db-name?useUnicode=true&characterEncoding=UTF-8&allowPublicKeyRetrieval=true&useSSL=false
spring.datasource.username=root
spring.datasource.password=root
shellhub
  • 2,695
  • 19
  • 14
  • right, simplest could be your local mysql password is something different that what is configured in application.properties .. go check and change that. This was the case with mw – Rajni Gangwar Mar 09 '21 at 12:28
4

First of all, please make sure your Database server is up and running. I was getting the same error, after trying all the answers listed here I found out that my Database server was not running.

You can check the same from MySQL Workbench, or Command line using

mysql -u USERNAME -p

This sounds obvious, but many times we assume that Database server is up and running all the time, especially when we are working on our local machine, when we restart/shutdown the machine, Database server will be shutdown automatically.

3

The above error in my case was actually due to the wrong username and password. Solving the issue: 1. Go to the line DriverManager.getConnection("jdbc:mysql://localhost:3306/?useSSL=false", "username", "password"); The fields username and password might be wrong. Enter the username and password which you use to start your mysql client. The username is generally root and password is the string which you enter when a screen similar to this appears Startup screen of mysql

Note: The portname 3306 might be different in your case.

risingStark
  • 1,036
  • 6
  • 15
3

This also can be happened due to wrong user name or password. As solutions I've added allowPublicKeyRetrieval=true&useSSL=false part but still I got error then I checked the password and it was wrong.

HashanR
  • 164
  • 12
1

This solution worked for MacOS Sierra, and running MySQL version 8.0.11. Please make sure driver you have added in your build path - "add external jar" should match up with SQL version.

String url = "jdbc:mysql://localhost:3306/syscharacterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true";
Stephen Rauch
  • 40,722
  • 30
  • 82
  • 105
surendrapanday
  • 349
  • 1
  • 11
1

In my case it was user error. I was using the root user with an invalid password. I am not sure why I didn't get an auth error but instead received this cryptic message.

juice
  • 1,632
  • 15
  • 11
1

I found this issue frustrating because I was able to interact with the database yesterday, but after coming back this morning, I started getting this error.

I tried adding the allowPublicKeyRetrieval=true flag, but I kept getting the error.

What fixed it for me was doing Project->Clean in Eclipse and Clean on my Tomcat server. One (or both) of those fixed it.

I don't understand why, because I build my project using Maven, and have been restarting my server after each code change. Very irritating...

Cameron Hudson
  • 1,573
  • 1
  • 14
  • 18
1

Give connection URL as jdbc:mysql://localhost:3306/hb_student_tracker?allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=UTC

1

Update the useSSL=true in spring boot application connection with mysql;

jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf8&useSSL=true&useLegacyDatetimeCode=false&serverTimezone=UTC
Bheem Singh
  • 432
  • 5
  • 10
1

I was also facing such an issue while dockerizing our existing application. The solution si to add allowPublicKeyRetrieval connection option of MySQL with a value of true to the JDBC connection string. If that is not working , try adding useSSL option to false as well .

The resultant string would look like this :

jdbc:mysql://<database server ip>:3306/databaseName?allowPublicKeyRetrieval=true&useSSL=false
Arun s
  • 507
  • 3
  • 13
0

If you are getting the following error while connecting the mysql (either local or mysql container running the mysql):

java.sql.SQLNonTransientConnectionException: Public Key Retrieval is not allowed

Solution: Add the following line in your database service:

command: --default-authentication-plugin=mysql_native_password
0

Setting Server Time Zone to my local place, fixed the issue.


ServerTimeZone

Manohar Reddy Poreddy
  • 16,412
  • 7
  • 111
  • 98