go-sql-driver/mysql · critical
no Pem data found, data: %s
Error message
no Pem data found, data: %s
What it means
Thrown in the sha256_password auth path (auth.go:463) when pem.Decode on the server's authData returns no PEM block. Unlike caching_sha2_password, here the server is expected to send its RSA public key directly in the auth response; if those bytes aren't a valid PEM key, parsing fails. Note the capital 'P' — distinct string from error 54.
Source
Thrown at auth.go:463
}
}
return mc.resultUnchanged().readResultOK()
default:
return ErrMalformPkt
}
default:
return ErrMalformPkt
}
case "sha256_password":
switch len(authData) {
case 0:
return nil // auth successful
default:
block, _ := pem.Decode(authData)
if block == nil {
return fmt.Errorf("no Pem data found, data: %s", authData)
}
pub, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return err
}
// send encrypted password
err = mc.sendEncryptedPassword(oldAuthData, pub.(*rsa.PublicKey))
if err != nil {
return err
}
return mc.resultUnchanged().readResultOK()
}
default:
return nil // auth successful
}View on GitHub (pinned to c426bd9379)
Solutions
- Enable TLS in the DSN so sha256_password uses cleartext over the encrypted channel and skips the key exchange.
- Inspect the %s bytes: if they resemble an error string, resolve the root auth failure first.
- Connect directly to MySQL, bypassing any proxy/router that may mangle the auth packet.
- Ensure the server is configured to provide its RSA public key (sha256_password_public_key_path / caching_sha2... server vars) if you must run without TLS.
Example fix
// before: sha256_password over plain TCP
// dsn := "user:pass@tcp(host:3306)/db"
// after: TLS removes the need for the key exchange
dsn := "user:pass@tcp(host:3306)/db?tls=skip-verify"
db, err := sql.Open("mysql", dsn) Defensive patterns
Strategy: validation
Validate before calling
// for sha256_password, TLS removes the need to receive/parse the server key
func sha256SafeDSN(user, pass, host, db string) string {
return fmt.Sprintf("%s:%s@tcp(%s)/%s?tls=true", user, pass, host, db)
} Try / catch
if err := db.PingContext(ctx); err != nil {
if strings.Contains(err.Error(), "no Pem data found") {
// enable TLS or unix socket and retry
}
} Prevention
- Run sha256_password connections over TLS or a unix socket.
- Ensure the server is configured to publish its RSA public key if TLS is off.
- Avoid proxies that rewrite the sha256_password auth payload.
When it happens
Trigger: Connecting to a server using the legacy sha256_password plugin over a non-TLS connection (the plugin requires RSA key exchange when TLS is absent), where the server's key payload is not parseable PEM — corrupted bytes, proxy mangling, or a non-conforming server.
Common situations: An older MySQL/MariaDB configured with sha256_password and no TLS; a proxy rewriting the auth payload; packet corruption; server configured to not advertise its key. The %s shows the offending bytes.
Related errors
- no pem data found, data: %s
- unexpected resp from server for caching_sha2_password, perfo
- invalid value / unknown config name: {cfg.TLSConfig}
- invalid value / unknown server pub key name: {cfg.ServerPubK
- invalid value for server pub key name: %v
AI-assisted analysis of go-sql-driver/mysql@c426bd9379 (2026-08-04).
Data as JSON: /data/errors/b8a4fdcd4abf5367.json.
Report an issue: GitHub.