go-sql-driver/mysql · error

no pem data found, data

Error message

no pem data found, data: %s

What it means

Returned at auth.go:432 during caching_sha2_password full auth: after the client requests the server public key, pem.Decode of the response (data[1:]) returns a nil block, meaning the bytes were not valid PEM-encoded key material.

Solutions

  1. Use TLS or unix socket so the cleartext path is taken and no key exchange occurs.
  2. Pin the server's public key via serverPubKey so the driver never parses a server-supplied key.
  3. Bypass or reconfigure any middleware that rewrites the auth payload.
  4. Verify the endpoint is a real MySQL 8+ server emitting a conformant RSA public key.

Example fix

// before: server key not parseable as PEM
dsn := "user:pass@tcp(mysql8:3306)/db"
// -> "no pem data found, data: ..."

// after: avoid dynamic key fetch entirely
dsn := "user:pass@tcp(mysql8:3306)/db?tls=true"
Defensive patterns

Strategy: fallback

Validate before calling

// Pin the public key so the client never has to parse a server-supplied one.
mysql.RegisterServerPubKey("mysql8", serverKeyPEM)
dsn := "user:pass@tcp(host:3306)/db?tls=true" // or ?serverPubKey=mysql8

Type guard

func isNoPemData(err error) bool {
    return err != nil && strings.Contains(err.Error(), "no pem data found")
}

Try / catch

if isNoPemData(err) {
    // take the TLS/cleartext path or pin the key; avoid parsing server key.
}

Prevention

When it happens

Trigger: caching_sha2_password over plaintext TCP where the server's public-key response is malformed or not PEM — a non-conformant server/proxy, truncated packet, or handshake tampering. Sibling of error 37 for the caching_sha2 path.

Common situations: Proxies/load balancers that strip or alter the public-key payload; buggy MySQL fork; packet truncation from MTU/MSS issues; connecting to something pretending to be MySQL.

Related errors


AI-assisted analysis of go-sql-driver/mysql@03d76c7e07 (2026-08-07). Data as JSON: /api/errors/8ce7bd4b42da2193. Report an issue: GitHub.

Appendix: source

Thrown at auth.go:432

						}
						data[4] = cachingSha2PasswordRequestPublicKey
						err = mc.writePacket(data)
						if err != nil {
							return err
						}

						if data, err = mc.readPacket(); err != nil {
							return err
						}

						if data[0] != iAuthMoreData {
							return fmt.Errorf("unexpected resp from server for caching_sha2_password, perform full authentication")
						}

						// parse public key
						block, rest := pem.Decode(data[1:])
						if block == nil {
							return fmt.Errorf("no pem data found, data: %s", rest)
						}
						pkix, err := x509.ParsePKIXPublicKey(block.Bytes)
						if err != nil {
							return err
						}
						pubKey = pkix.(*rsa.PublicKey)
					}

					// send encrypted password
					err = mc.sendEncryptedPassword(oldAuthData, pubKey)
					if err != nil {
						return err
					}
				}
				return mc.resultUnchanged().readResultOK()

			default:
				return ErrMalformPkt

View on GitHub (pinned to 03d76c7e07)