GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — mysql: track the auth plugin and seed from an authentication switch request by kibo-andynunes · Pull Request #440 · jasync-sql/jasync-sql

Conversation

@kibo-andynunes

@kibo-andynunes kibo-andynunes commented Nov 4, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

mysql: track the auth plugin and seed from an authentication switch request

Fixes #441

Problem

MySQLConnection stores authenticationMethod and authenticationSeed from the initial handshake only (onHandshake). switchAuthentication() answers the server's authentication switch request but never records the plugin and seed it carries.

That breaks any server whose default plugin differs from the account's plugin, for example:

  • the handshake advertises mysql_native_password (server default, e.g. default_authentication_plugin=mysql_native_password, or a managed MySQL 8.0 service), but
  • the account uses caching_sha2_password.

The flow is: handshake (native) -> client response -> auth switch request (caching_sha2_password, new seed) -> client scramble -> AuthMoreData(0x04) (cold server cache, full authentication required). onAuthMoreData then checks the stale handshake plugin and throws:

java.lang.IllegalStateException: AuthMoreDataMessage is only supported for 'caching_sha2_password' method

Every new connection fails while the server's caching_sha2_password cache is cold (after a restart, FLUSH PRIVILEGES, ALTER USER), and works again once another client has populated the cache (AuthMoreData(0x03) is accepted without looking at the plugin). Even with the plugin check fixed, the RSA path would scramble the password with the stale handshake seed instead of the seed from the switch request, so both values need updating.

Not a TLS/sslMode issue: it fails identically with Mode.Disable and Mode.Prefer.

Fix

Record the plugin and seed from the switch request before answering it:

override fun switchAuthentication(message: AuthenticationSwitchRequest) {
    this.authenticationMethod = message.method
    this.authenticationSeed = message.seed
    ...
}

No behavior change when the handshake and the account use the same plugin (no switch happens).

Tests

  • AuthenticationSpec.cachingSha2PasswordAuthenticationWhenServerAdvertisesNativePasswordInHandshake: real MySQL 8.0.32 started with --default-authentication-plugin=mysql_native_password, accounts created WITH caching_sha2_password. Mirrors the existing cachingSha2PasswordAuthentication test: cold cache without SSL fails with the unsafe-connection error, full authentication with SSL, fast authentication, full authentication with an RSA public key.
  • AuthenticationSwitchSpec (new, no Docker): an in-process fake MySQL server scripts the exact packets, which also covers things a real server can't be made to do on demand:
    • full authentication after a switch from a native handshake scrambles the password with the switch seed (the server side decrypts the RSA packet and checks it);
    • fast authentication after a switch sends nothing further;
    • full authentication without a switch still uses the handshake seed (regression guard);
    • full authentication after a switch with no SSL and no RSA key fails with the existing unsafe-connection error;
    • a switch to mysql_native_password completes;
    • AuthMoreData after a switch away from caching_sha2_password is rejected (the plugin check now reflects the plugin actually in use).

Verification

Run Result
New real-server test, with fix pass
New real-server test, fix reverted fails with AuthMoreDataMessage is only supported for 'caching_sha2_password' method
AuthenticationSwitchSpec (6 tests), with fix 6/6 pass
AuthenticationSwitchSpec, fix reverted 3 fail (the switch cases)
AuthenticationSwitchSpec, plugin line only (seed line removed) the RSA/seed test fails (password decrypts to garbage), so both lines are needed
AuthenticationSpec (all 5, incl. sha256 and old-password flows), with fix pass
:mysql-async:test + :r2dbc-mysql:test, with fix no failures attributable to the change (see note)
ktlintCheck pass

Note: on my machine (Apple silicon, Docker Desktop) MySQLConnectionSpec."connect to a MySQL instance with unix domain socket" fails with and without the change (connection refused), and sha256Authentication failed once in the full run on container startup (mysql:5.7.32) and passed when rerun. Neither relates to this change.

Run locally with JDK 17 and -PTEST_CONTAINERS_VERSION=1.21.4: the pinned Testcontainers 1.17.6 can't talk to a current Docker daemon (API too old). That override is not part of this PR.


🤖 Generated with Claude Code

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@kibo-andynunes @claude
mysql: track the auth plugin and seed from an authentication switch r…
32ecdce
…equest

MySQLConnection stored the authentication method and seed from the initial
handshake only. When the server's default plugin differs from the account's
plugin (e.g. the handshake advertises mysql_native_password but the account uses
caching_sha2_password), the server answers with an authentication switch request.
switchAuthentication() answered it but did not record the new plugin and seed, so
a following AuthMoreData packet asking for full authentication was checked
against the stale plugin and failed with:

  AuthMoreDataMessage is only supported for 'caching_sha2_password' method

It also scrambled the password with the stale seed on the RSA path.

Record the plugin and seed from the switch request before answering it.

Tests: AuthenticationSpec gets a case against a real server whose default plugin
is mysql_native_password; AuthenticationSwitchSpec covers the packet flows
against an in-process fake server without Docker.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
@kibo-andynunes kibo-andynunes mentioned this pull request Nov 4, 2026
IllegalStateException "AuthMoreDataMessage is only supported for 'caching_sha2_password' method" when the handshake plugin differs from the account's plugin #441
Closed
@kibo-andynunes

kibo-andynunes commented Nov 5, 2026

Copy link
Copy Markdown
Contributor Author

Note on the red checks, neither comes from this change:

  • Greetings: actions/first-interaction@v1 fails with Resource not accessible by integration when it tries to post its welcome review. pull_request workflows from a fork get a read-only GITHUB_TOKEN, so this fails for any first-time fork PR (it also failed on the earlier chore/update-kotlin-logging PR). It would need pull_request_target to work.
  • CI: the build stops at :postgis-jasync:test (all 4 PostgisSpec tests fail in the Testcontainers-based ContainerHelper, before any query runs). ubuntu-latest moved to ubuntu-26.04 on Oct 19, and the repo pins Testcontainers 1.17.6; locally that version can't talk to a current Docker daemon either (it works with -PTEST_CONTAINERS_VERSION=1.21.4). I haven't confirmed this is the exact error on the runner, since the log only shows IllegalStateException. Because Gradle stops there, :mysql-async:test never ran in this job.

The new AuthenticationSpec test needs Docker, so it hits the same Testcontainers problem on the runner; AuthenticationSwitchSpec does not use Docker. Both pass locally. ktlint passes.

Happy to send a separate PR bumping Testcontainers (or pinning the runner) if you'd like.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@oshai
oshai merged commit e9e901f into jasync-sql:master Nov 6, 2026
1 of 3 checks passed

Uh oh!

There was an error while loading. Please reload this page.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

IllegalStateException "AuthMoreDataMessage is only supported for 'caching_sha2_password' method" when the handshake plugin differs from the account's plugin

Uh oh!

There was an error while loading. Please reload this page.

2 participants

@kibo-andynunes @oshai
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402520 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.