{"id":"6d33332d9c776572","repo":"sidorares/node-mysql2","slug":"unexpected-data-in-authmoredata-packet-received-by","errorCode":null,"errorMessage":"Unexpected data in AuthMoreData packet received by caching_sha2_password plugin in STATE_FINAL state.","messagePattern":"Unexpected data in AuthMoreData packet received by caching_sha2_password plugin in STATE_FINAL state\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/auth_plugins/caching_sha2_password.js","lineNumber":100,"sourceCode":"\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          throw new Error(\n            `Invalid AuthMoreData packet received by ${PLUGIN_NAME} plugin in STATE_TOKEN_SENT state.`\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\n// Export the plugin factory as default\nmodule.exports = pluginFactory;\n\n// Export calculateToken for reuse in initial handshake optimization\nmodule.exports.calculateToken = calculateToken;\n","sourceCodeStart":82,"sourceCodeEnd":116,"githubUrl":"https://github.com/sidorares/node-mysql2/blob/5ebe8903d6aea2d8ea1490e11b52491526e50f19/lib/auth_plugins/caching_sha2_password.js#L82-L116","documentation":"The caching_sha2_password plugin reached STATE_FINAL (meaning authentication is logically complete — either fast-auth succeeded or the full password was sent encrypted), but the server subsequently sent another AuthMoreData packet. The plugin has no further work to do, so any extra data is treated as a protocol desync. This almost always indicates the client and server have fallen out of sync about where they are in the auth conversation.","triggerScenarios":"The server sends an extra AuthMoreData packet after the plugin already returned its final auth payload. Observed with certain proxy/interceptor setups that replay or duplicate auth packets, or when a connection is silently re-attached to a different backend mid-handshake (connection-pool multiplexing in a proxy).","commonSituations":"Using a database proxy that multiplexes or routes connections (ProxySQL, RDS Proxy, HAProxy with L7 modes) behind a caching_sha2_password server; connecting through an SSH tunnel or VPN that duplicates/reorders packets; a server bug in an early MySQL 8.0.x release.","solutions":["Bypass the proxy/tunnel and connect directly to the MySQL server to confirm the intermediary is the cause.","Upgrade the proxy software or disable connection-multiplexing/replay for auth-bearing connections.","Enable SSL on the mysql2 connection; some intermediaries pass encrypted auth through untouched.","Upgrade mysql2 and the MySQL server to current patch releases.","As a workaround, switch the MySQL user to mysql_native_password if the environment permits."],"exampleFix":"// before — direct, no TLS, behind a multiplexing proxy\nconst pool = mysql.createPool({ host: proxyHost, user, password });\n\n// after — pin to single backend / disable proxy auth replay, and use TLS\nconst pool = mysql.createPool({\n  host: realDbHost,\n  user,\n  password,\n  ssl: { rejectUnauthorized: true },\n});","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const conn = await mysql.createConnection(cfg);\n} catch (err) {\n  if (/Unexpected data in AuthMoreData.*STATE_FINAL.*caching_sha2_password/.test(err.message)) {\n    // retry bypassing the proxy, or with TLS enabled\n  } else throw err;\n}","preventionTips":["Avoid L7 proxies that replay auth packets for caching_sha2_password accounts.","Use direct connections during connection-pool warm-up debugging.","Enable TLS to reduce middleware interference."],"tags":["auth","caching-sha2-password","protocol","connection","proxy"],"analyzedSha":"5ebe8903d6aea2d8ea1490e11b52491526e50f19","analyzedAt":"2026-08-03T18:58:53.602Z","schemaVersion":2}