sidorares/node-mysql2 · error · Error

Unexpected data in AuthMoreData packet received by caching_s

Error message

Unexpected data in AuthMoreData packet received by caching_sha2_password plugin in STATE_FINAL state.

What it means

The caching_sha2_password plugin reached STATE_FINAL (meaning authentication is logically complete — either fast-auth succeeded or the full password was sent encrypted), but the server subsequently sent another AuthMoreData packet. The plugin has no further work to do, so any extra data is treated as a protocol desync. This almost always indicates the client and server have fallen out of sync about where they are in the auth conversation.

Source

Thrown at lib/auth_plugins/caching_sha2_password.js:100

            // if client provides key we can save one extra roundrip on first connection
            if (pluginOptions.serverPublicKey) {
              return authWithKey(pluginOptions.serverPublicKey);
            }

            state = STATE_WAIT_SERVER_KEY;
            return REQUEST_SERVER_KEY_PACKET;
          }
          throw new Error(
            `Invalid AuthMoreData packet received by ${PLUGIN_NAME} plugin in STATE_TOKEN_SENT state.`
          );
        case STATE_WAIT_SERVER_KEY:
          if (pluginOptions.onServerPublicKey) {
            pluginOptions.onServerPublicKey(data);
          }
          return authWithKey(data);
        case STATE_FINAL:
          throw new Error(
            `Unexpected data in AuthMoreData packet received by ${PLUGIN_NAME} plugin in STATE_FINAL state.`
          );
      }

      throw new Error(
        `Unexpected data in AuthMoreData packet received by ${PLUGIN_NAME} plugin in state ${state}`
      );
    };
  };

// Export the plugin factory as default
module.exports = pluginFactory;

// Export calculateToken for reuse in initial handshake optimization
module.exports.calculateToken = calculateToken;

View on GitHub (pinned to 5ebe8903d6)

Solutions

  1. Bypass the proxy/tunnel and connect directly to the MySQL server to confirm the intermediary is the cause.
  2. Upgrade the proxy software or disable connection-multiplexing/replay for auth-bearing connections.
  3. Enable SSL on the mysql2 connection; some intermediaries pass encrypted auth through untouched.
  4. Upgrade mysql2 and the MySQL server to current patch releases.
  5. As a workaround, switch the MySQL user to mysql_native_password if the environment permits.

Example fix

// before — direct, no TLS, behind a multiplexing proxy
const pool = mysql.createPool({ host: proxyHost, user, password });

// after — pin to single backend / disable proxy auth replay, and use TLS
const pool = mysql.createPool({
  host: realDbHost,
  user,
  password,
  ssl: { rejectUnauthorized: true },
});
Defensive patterns

Strategy: try-catch

Try / catch

try {
  const conn = await mysql.createConnection(cfg);
} catch (err) {
  if (/Unexpected data in AuthMoreData.*STATE_FINAL.*caching_sha2_password/.test(err.message)) {
    // retry bypassing the proxy, or with TLS enabled
  } else throw err;
}

Prevention

When it happens

Trigger: The server sends an extra AuthMoreData packet after the plugin already returned its final auth payload. Observed with certain proxy/interceptor setups that replay or duplicate auth packets, or when a connection is silently re-attached to a different backend mid-handshake (connection-pool multiplexing in a proxy).

Common situations: Using a database proxy that multiplexes or routes connections (ProxySQL, RDS Proxy, HAProxy with L7 modes) behind a caching_sha2_password server; connecting through an SSH tunnel or VPN that duplicates/reorders packets; a server bug in an early MySQL 8.0.x release.

Related errors


AI-assisted analysis of sidorares/node-mysql2@5ebe8903d6 (2026-08-03). Data as JSON: /data/errors/6d33332d9c776572.json. Report an issue: GitHub.