sidorares/node-mysql2 · error · Error

Unexpected data in AuthMoreData packet received by sha256_pa

Error message

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

What it means

The sha256_password plugin reached STATE_FINAL (the password was already sent, encrypted with the server's RSA public key), yet the server sent another AuthMoreData packet. Like the caching_sha2_password equivalent, the plugin has no further auth step to perform, so extra data signals a client/server protocol desync.

Source

Thrown at lib/auth_plugins/sha256_password.js:65

            return Buffer.from(`${password}\0`, 'utf8');
          }

          scramble = data.slice(0, 20);
          // 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;

        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 5ebe8903d6)

Solutions

  1. Connect directly to mysqld (bypassing any proxy) to isolate the source.
  2. Enable TLS/SSL on the connection so the password is sent in cleartext over the secure channel and the multi-step RSA exchange is avoided.
  3. Update the proxy/middleware or disable its auth-packet inspection/replay.
  4. Upgrade MySQL server and mysql2 to current releases.
  5. If possible, switch the account to caching_sha2_password or mysql_native_password.

Example fix

// before
const conn = mysql.createConnection({ host, user, password }); // account uses sha256_password

// after — TLS lets sha256_password skip the RSA round-trips
const conn = mysql.createConnection({
  host,
  user,
  password,
  ssl: { rejectUnauthorized: true },
});
Defensive patterns

Strategy: try-catch

Try / catch

try {
  const conn = await mysql.createConnection({ ...cfg, ssl: { rejectUnauthorized: true } });
} catch (err) {
  if (/Unexpected data in AuthMoreData.*sha256_password.*STATE_FINAL/.test(err.message)) {
    // bypass proxy or switch account plugin
  } else throw err;
}

Prevention

When it happens

Trigger: Connecting to a MySQL server configured with the sha256_password plugin (less common than caching_sha2_password) where the server emits a spurious AuthMoreData after the client already delivered the RSA-encrypted password. Seen with proxies that replay auth packets or with buggy server builds.

Common situations: A MySQL user account explicitly set to sha256_password; a proxy or connection-pooler interfering with the auth sequence; an older MySQL 5.7 server with known auth-edge bugs; connecting through middleware that does not understand the sha256_password flow.

Related errors


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