sidorares/node-mysql2 · error · Error

Unexpected data in AuthMoreData packet received by ${PLUGIN_

Error message

Unexpected data in AuthMoreData packet received by ${PLUGIN_NAME} plugin in STATE_FINAL state.

What it means

sha256_password plugin equivalent of error [1]: once the plugin reaches STATE_FINAL (-1) after encrypting the password with the server's RSA key (lib/auth_plugins/sha256_password.js:33-36, 64-67), no further AuthMoreData packets are expected. Receiving one means the server sent unsolicited data after auth completion — a 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 8b1f829d37)

Solutions

  1. Prefer TLS (config.ssl) so the plugin takes the early-return cleartext path and never enters the RSA round-trip that ends in STATE_FINAL-with-trailing-data.
  2. Eliminate connection-pool socket reuse of errored connections.
  3. Upgrade mysql2 and verify against the server's exact version.

Example fix

// before: non-TLS sha256_password path hits RSA exchange
const conn = mysql.createConnection({ host, user, password });

// after: TLS short-circuits the exchange at STATE_INITIAL
const conn = mysql.createConnection({ host, user, password, ssl: { rejectUnauthorized: true } });
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await mysql.createConnection({ host, user, password, ssl: { rejectUnauthorized: true } });
} catch (e) {
  if (/sha256_password.*STATE_FINAL/.test(e.message)) { /* TLS short-circuit failed; verify cert + server */ }
  throw e;
}

Prevention

When it happens

Trigger: Connecting to a server configured with sha256_password (common on MySQL 5.7 enterprise or hardened setups) over a non-TLS connection; the server sends trailing data after the encrypted password was accepted; connection reused from a pool with stale auth state.

Common situations: Migrating from mysql_native_password to sha256_password for FIPS/compliance reasons; a server-side load balancer that injects a monitoring packet after auth; pool reuse of a half-closed socket.

Related errors


AI-assisted analysis of sidorares/node-mysql2@8b1f829d37 (2026-08-11). Data as JSON: /api/errors/c82a8afe9864ebb7. Report an issue: GitHub.