{"record":{"id":"c82a8afe9864ebb7","repo":"sidorares/node-mysql2","slug":"unexpected-data-in-authmoredata-packet-received-by-c82a8a","errorCode":null,"errorMessage":"Unexpected data in AuthMoreData packet received by ${PLUGIN_NAME} plugin in STATE_FINAL state.","messagePattern":"Unexpected data in AuthMoreData packet received by (.+?) plugin in STATE_FINAL state\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/auth_plugins/sha256_password.js","lineNumber":65,"sourceCode":"            return Buffer.from(`${password}\\0`, 'utf8');\n          }\n\n          scramble = data.slice(0, 20);\n          // if client provides key we can save one extra roundrip on first connection\n          if (pluginOptions.serverPublicKey) {\n            return authWithKey(pluginOptions.serverPublicKey);\n          }\n\n          state = STATE_WAIT_SERVER_KEY;\n          return REQUEST_SERVER_KEY_PACKET;\n\n        case STATE_WAIT_SERVER_KEY:\n          if (pluginOptions.onServerPublicKey) {\n            pluginOptions.onServerPublicKey(data);\n          }\n          return authWithKey(data);\n        case STATE_FINAL:\n          throw new Error(\n            `Unexpected data in AuthMoreData packet received by ${PLUGIN_NAME} plugin in STATE_FINAL state.`\n          );\n      }\n\n      throw new Error(\n        `Unexpected data in AuthMoreData packet received by ${PLUGIN_NAME} plugin in state ${state}`\n      );\n    };\n  };\n","sourceCodeStart":47,"sourceCodeEnd":75,"githubUrl":"https://github.com/sidorares/node-mysql2/blob/8b1f829d3706404ab372cf97bd77ebcf86578d97/lib/auth_plugins/sha256_password.js#L47-L75","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["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.","Eliminate connection-pool socket reuse of errored connections.","Upgrade mysql2 and verify against the server's exact version."],"exampleFix":"// before: non-TLS sha256_password path hits RSA exchange\nconst conn = mysql.createConnection({ host, user, password });\n\n// after: TLS short-circuits the exchange at STATE_INITIAL\nconst conn = mysql.createConnection({ host, user, password, ssl: { rejectUnauthorized: true } });","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await mysql.createConnection({ host, user, password, ssl: { rejectUnauthorized: true } });\n} catch (e) {\n  if (/sha256_password.*STATE_FINAL/.test(e.message)) { /* TLS short-circuit failed; verify cert + server */ }\n  throw e;\n}","preventionTips":["Use TLS with sha256_password so the plugin returns the cleartext password at STATE_INITIAL and never reaches STATE_FINAL trailing-data.","Avoid pool reuse of errored sockets."],"tags":["authentication","sha256-password","network","protocol"],"backgroundTag":null,"analyzedSha":"8b1f829d3706404ab372cf97bd77ebcf86578d97","analyzedAt":"2026-08-11T02:54:28.964Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}