{"record":{"id":"fd4cceb256f1494b","repo":"go-sql-driver/mysql","slug":"unexpected-resp-from-server-for-caching-sha2-passw","errorCode":null,"errorMessage":"unexpected resp from server for caching_sha2_password, perform full authentication","messagePattern":"unexpected resp from server for caching_sha2_password, perform full authentication","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"auth.go","lineNumber":426,"sourceCode":"\t\t\t\t\tpubKey := mc.cfg.pubKey\n\t\t\t\t\tif pubKey == nil {\n\t\t\t\t\t\t// request public key from server\n\t\t\t\t\t\tdata, err := mc.buf.takeSmallBuffer(4 + 1)\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\treturn err\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdata[4] = cachingSha2PasswordRequestPublicKey\n\t\t\t\t\t\terr = mc.writePacket(data)\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\treturn err\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif data, err = mc.readPacket(); err != nil {\n\t\t\t\t\t\t\treturn err\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif data[0] != iAuthMoreData {\n\t\t\t\t\t\t\treturn fmt.Errorf(\"unexpected resp from server for caching_sha2_password, perform full authentication\")\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// parse public key\n\t\t\t\t\t\tblock, rest := pem.Decode(data[1:])\n\t\t\t\t\t\tif block == nil {\n\t\t\t\t\t\t\treturn fmt.Errorf(\"no pem data found, data: %s\", rest)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tpkix, err := x509.ParsePKIXPublicKey(block.Bytes)\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\treturn err\n\t\t\t\t\t\t}\n\t\t\t\t\t\tpubKey = pkix.(*rsa.PublicKey)\n\t\t\t\t\t}\n\n\t\t\t\t\t// send encrypted password\n\t\t\t\t\terr = mc.sendEncryptedPassword(oldAuthData, pubKey)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn err","sourceCodeStart":408,"sourceCodeEnd":444,"githubUrl":"https://github.com/go-sql-driver/mysql/blob/03d76c7e07908e255ce62d126d07ede3f2365d86/auth.go#L408-L444","documentation":"Returned during caching_sha2_password full authentication over a non-TLS, non-unix connection (auth.go:426). The client requests the server's RSA public key and expects an AuthMoreData (0x01) frame; if the first byte of the response differs, the handshake is treated as broken.","triggerScenarios":"First (uncached) login of a caching_sha2_password user over plaintext TCP without a configured server public key, where the server's response is not the expected AuthMoreData frame — e.g. a proxy/MITM altering the handshake, a server bug, or stream corruption during key exchange.","commonSituations":"MySQL 8.0 default auth (caching_sha2_password) over unencrypted networks; a load balancer or connection-pooling proxy that doesn't pass through auth-more-data; first connection after server restart (cache cold).","solutions":["Use TLS (tls=true) or a unix socket so the driver sends the password as cleartext and skips key exchange entirely.","Pre-load the server's RSA public key via the DSN (serverPubKey=<name> registered with mysql.RegisterServerPubKey) to avoid requesting it dynamically.","Remove any proxy that rewrites the auth handshake, or configure it to be fully transparent.","Upgrade the server/proxy to a version that correctly implements caching_sha2_password full auth."],"exampleFix":"// before: plaintext TCP, cold cache -> key-exchange desync\ndsn := \"user:pass@tcp(mysql8:3306)/db\"\n\n// after: TLS removes the need for the public-key exchange\ndsn := \"user:pass@tcp(mysql8:3306)/db?tls=true\"\n// or pin the key:\n//   mysql.RegisterServerPubKey(\"mysql8\", pemBytes)\n//   dsn := \"...?serverPubKey=mysql8\"","handlingStrategy":"retry","validationCode":"// Avoid the dynamic key exchange entirely: prefer TLS/unix or pin the key.\nif !tlsAvailable && serverPubKeyPEM == \"\" {\n    return errors.New(\"caching_sha2 over plaintext needs TLS or a pinned pubkey\")\n}","typeGuard":"func isCachingSha2BadResp(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"caching_sha2_password, perform full authentication\")\n}","tryCatchPattern":"if isCachingSha2BadResp(err) {\n    // switch to TLS/unix, or pin serverPubKey, then retry the connection.\n}","preventionTips":["Use tls=true or unix sockets for caching_sha2_password accounts.","Pre-register the server key with mysql.RegisterServerPubKey and reference it via serverPubKey.","Remove proxies that alter the auth-more-data handshake."],"tags":["authentication","caching-sha2","handshake","security"],"backgroundTag":null,"analyzedSha":"03d76c7e07908e255ce62d126d07ede3f2365d86","analyzedAt":"2026-08-07T10:39:17.340Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}