sidorares/node-mysql2 · critical · Error
Invalid AuthMoreData packet received by ${PLUGIN_NAME} plugi
Error message
Invalid AuthMoreData packet received by ${PLUGIN_NAME} plugin in STATE_TOKEN_SENT state. What it means
Thrown by the caching_sha2_password auth plugin when, after the client sent its scrambled password token (STATE_TOKEN_SENT), the server replies with an AuthMoreData packet whose first byte is neither 0x03 (fast-auth success) nor 0x04 (perform full authentication). The plugin's state machine at lib/auth_plugins/caching_sha2_password.js:67-93 only recognizes those two bytes, so any other leading byte is treated as a protocol violation. It almost always indicates a malformed or intercepted auth exchange rather than a normal client misconfiguration.
Source
Thrown at lib/auth_plugins/caching_sha2_password.js:91
if (PERFORM_FULL_AUTHENTICATION_PACKET.equals(data)) {
const isSecureConnection =
typeof pluginOptions.overrideIsSecure === 'undefined'
? connection.config.ssl || connection.config.socketPath
: pluginOptions.overrideIsSecure;
if (isSecureConnection) {
state = STATE_FINAL;
return Buffer.from(`${password}\0`, 'utf8');
}
// 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}`
);
};
};View on GitHub (pinned to 8b1f829d37)
Solutions
- Verify the MySQL server version and that no proxy/pooler is intercepting the auth handshake (connect directly to the mysqld port).
- Force a clear protocol by either enabling SSL (set config.ssl) or downgrading the server account to mysql_native_password (ALTER USER ... IDENTIFIED WITH mysql_native_password) to bypass caching_sha2_password entirely.
- If a proxy is required, upgrade or reconfigure it to be transparent for the auth phase, or pin the connection to a single backend node.
- Update mysql2 to the latest release, since auth-state-machine fixes land frequently.
Example fix
// before: plaintext connection through an intercepting proxy
const conn = mysql.createConnection({ host: 'proxy', user: 'u', password: 'p' });
// after: TLS so the proxy cannot rewrite the auth exchange
const conn = mysql.createConnection({ host: 'db', user: 'u', password: 'p', ssl: { rejectUnauthorized: true } }); Defensive patterns
Strategy: try-catch
Try / catch
try {
const conn = await mysql.createConnection({ host, user, password, ssl: { rejectUnauthorized: true } });
} catch (e) {
if (/caching_sha2_password.*STATE_TOKEN_SENT/.test(e.message)) {
// auth exchange tampered/proxied: bypass proxy or enable TLS
}
throw e;
} Prevention
- Always enable TLS (config.ssl) for caching_sha2_password so the full-auth RSA path is avoided.
- Connect directly to mysqld during debugging to rule out intercepting proxies.
- Keep mysql2 on the latest release to pick up auth state-machine fixes.
When it happens
Trigger: Connecting to a MySQL 8.x server whose default auth plugin is caching_sha2_password, where an intermediary (proxy, man-in-the-middle, buggy connection pooler like a stale PgBouncer-style proxy) rewrites or truncates the AuthMoreData packet. Also reproducible when the server's cached auth state is corrupted, or when the connection is half-closed and stale bytes are read as an auth packet.
Common situations: Upgrading a MySQL server from 5.7 (mysql_native_password) to 8.x (caching_sha2_password) behind a proxy that does not understand the new plugin's multi-step flow; using a load balancer that buffers/rewrites auth packets; a network device corrupting the SSL handshake so the client misreads encrypted bytes as a cleartext AuthMoreData packet.
Related errors
- Unexpected data in AuthMoreData packet received by ${PLUGIN_
- Unexpected data in AuthMoreData packet received by ${PLUGIN_
- Unexpected data in AuthMoreData packet received by ${PLUGIN_
- Unexpected data in AuthMoreData packet received by ${PLUGIN_
- Server requests authentication using unknown plugin ${plugin
AI-assisted analysis of sidorares/node-mysql2@8b1f829d37 (2026-08-11).
Data as JSON: /api/errors/256b1b61a595aef5.
Report an issue: GitHub.