{"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":"critical","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/c426bd93799de0f0e094c8f0582872c529d0ed0a/auth.go#L408-L444","documentation":"Thrown in the caching_sha2_password full-auth path (auth.go:426) when, after the client requests the server's RSA public key, the first byte of the response is not iAuthMoreData (0x01). The client expected the server to send its public key; getting a different leading byte means the protocol state is unexpected — typically the server sent an error or an auth-result packet instead.","triggerScenarios":"Connecting with caching_sha2_password (MySQL 8 default) over a non-TLS, non-unix-socket connection WITHOUT a preconfigured server public key, where the server's response to the public-key request is not a key blob — e.g. the server replied with an error or terminated auth.","commonSituations":"MySQL 8+ over plain TCP with no TLS and no allowOldPasswords/serverPubKey configured; an intermediary (proxy, RDS proxy) that rewrites the auth handshake; a server that rejects the account mid-handshake; version/compatibility skew between client and server auth plugins.","solutions":["Enable TLS in the DSN (tls=true or a registered tls config) so the driver uses cleartext auth over an encrypted channel instead of requesting a public key.","Use a unix socket (net=unix) which also takes the cleartext-auth fast path.","Provide the server RSA public key via the DSN (allowOldPasswords / server pub key registration) to skip the request step.","Verify the server actually supports caching_sha2_password and the account is not locked/expired; test the same credentials in the mysql CLI."],"exampleFix":"// before: plain TCP, no TLS\n// dsn := \"user:pass@tcp(host:3306)/db\"\n\n// after: enable TLS so full auth uses cleartext over encrypted channel\ndsn := \"user:pass@tcp(host:3306)/db?tls=true\"\ndb, err := sql.Open(\"mysql\", dsn)","handlingStrategy":"validation","validationCode":"// build a DSN that avoids the public-key request path\nfunc mysqlDSN(user, pass, host, db string) string {\n    // tls=true makes caching_sha2_password use cleartext over TLS\n    return fmt.Sprintf(\"%s:%s@tcp(%s)/%s?tls=true\", user, pass, host, db)\n}\n// or use net=unix to take the cleartext fast path","typeGuard":null,"tryCatchPattern":"db, err := sql.Open(\"mysql\", dsn)\nif err := db.PingContext(ctx); err != nil {\n    if strings.Contains(err.Error(), \"unexpected resp from server for caching_sha2_password\") {\n        // switch DSN to tls=true / unix socket and retry\n    }\n}","preventionTips":["Always connect to MySQL 8+ over TLS or a unix socket to avoid the RSA key-exchange path.","Pre-register the server RSA public key in the DSN if you must run without TLS.","Verify the account is not locked/expired by testing in the mysql CLI."],"tags":["auth","caching-sha2","tls","mysql8","handshake"],"analyzedSha":"c426bd93799de0f0e094c8f0582872c529d0ed0a","analyzedAt":"2026-08-04T21:52:59.219Z","schemaVersion":2}