sidorares/node-mysql2 · critical · Error
Server requests authentication using unknown plugin
Error message
Server requests authentication using unknown plugin ${pluginName}. See ${'TODO: add plugins doco here'} on how to configure or author authentication plugins. What it means
In authSwitchRequest (lib/commands/auth_switch.js:97-102), the server's AuthSwitchRequest names a plugin that is neither one of the four built-ins (caching_sha2_password, sha256_password, mysql_native_password, mysql_clear_password) nor present in connection.config.authPlugins. The driver cannot proceed without an implementation of that plugin, so it throws fatal. The message still references a TODO doc URL that has not been filled in.
Solutions
- Provide a custom plugin implementation via createConnection({ authPlugins: { '<pluginName>': pluginFactory } }).
- Change the server account to a supported plugin: ALTER USER ... IDENTIFIED WITH 'mysql_native_password' (or caching_sha2_password) BY 'pw'.
- Upgrade mysql2 — newer releases add built-in support for more plugins.
- For MariaDB ed25519, install/use a compatible client or implement the authPlugins callback.
Example fix
// before
const conn = mysql.createConnection({ host, user, password });
// after: supply the missing plugin factory
const conn = mysql.createConnection({
host, user, password,
authPlugins: { ed25519: ed25519PluginFactory },
}); Defensive patterns
Strategy: validation
Validate before calling
const knownPlugins = ['caching_sha2_password','sha256_password','mysql_native_password','mysql_clear_password'];
if (!knownPlugins.includes(serverPlugin) && !(config.authPlugins || {})[serverPlugin]) {
throw new Error(`Provide authPlugins.${serverPlugin} or ALTER USER to a supported plugin.`);
} Type guard
const isKnownPlugin = (name, authPlugins = {}) =>
['caching_sha2_password','sha256_password','mysql_native_password','mysql_clear_password'].includes(name) || Object.prototype.hasOwnProperty.call(authPlugins, name); Try / catch
try { await mysql.createConnection(cfg); } catch (e) { if (/unknown plugin/.test(e.message)) { /* add authPlugins entry or ALTER USER */ } throw e; } Prevention
- Pre-create authPlugins entries for every plugin the fleet uses.
- Pin server accounts to a client-supported plugin via ALTER USER.
When it happens
Trigger: MySQL server account pinned to an auth plugin the client does not ship (e.g. ed25519 on MariaDB, or an enterprise PAM/LDAP plugin); a MariaDB server defaulting to a plugin not in the standard set; connecting to an AWS Aurora or ProxySQL instance that advertises a custom plugin name.
Common situations: MariaDB with unix_socket or ed25519; a hardened server using auth_pam; newer server advertising a plugin the older mysql2 client predates.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- AuthPluginMoreData received but no auth plugin instance…
- HandshakeResponse authPluginName must be a string when…
- HandshakeResponse authToken must be a Buffer when provided
- Invalid AuthMoreData packet received by
- Unexpected data in AuthMoreData packet received by
AI-assisted analysis of sidorares/node-mysql2@8b1f829d37 (2026-08-11).
Data as JSON: /api/errors/46a11e07818edcef.
Report an issue: GitHub.
Appendix: source
Thrown at lib/commands/auth_switch.js:99
);
if (!hasCustomPlugin && !connection.config.enableCleartextPlugin) {
const err = new Error(
'Server requested authentication using mysql_clear_password, ' +
'which sends the password in plaintext over the network and is ' +
'disabled by default. To enable it, set the `enableCleartextPlugin` ' +
'option to `true` in your connection configuration, or provide a ' +
'custom `mysql_clear_password` auth plugin via the `authPlugins` ' +
'option. Only use this over a secure connection (TLS/SSL).'
);
err.code = 'MYSQL_CLEAR_PASSWORD_NOT_ENABLED';
err.fatal = true;
throw err;
}
}
const authPlugin = getAuthPlugin(pluginName, connection);
if (!authPlugin) {
throw new Error(
`Server requests authentication using unknown plugin ${pluginName}. See ${'TODO: add plugins doco here'} on how to configure or author authentication plugins.`
);
}
connection._authPlugin = authPlugin({ connection, command });
Promise.resolve(connection._authPlugin(pluginData))
.then((data) => {
if (data) {
connection.writePacket(new Packets.AuthSwitchResponse(data).toPacket());
}
})
.catch((err) => {
authSwitchPluginError(err, command);
});
}
function authSwitchRequestMoreData(packet, connection, command) {
const { data } = Packets.AuthSwitchRequestMoreData.fromPacket(packet);
View on GitHub (pinned to 8b1f829d37)