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:463 during sha256_password authentication: pem.Decode of the auth data returns nil, so the server's RSA public key (needed to encrypt the password on a non-TLS link) could not be parsed. Note the message capitalizes 'Pem' differently from the caching_sha2 variant (error 36).

Solutions

  1. Use TLS so the password is sent as cleartext over the encrypted channel (no RSA exchange).
  2. Pin the server public key with serverPubKey to skip parsing a server-supplied key.
  3. Make any intermediary fully transparent to the auth handshake.
  4. Validate the server returns standards-compliant PEM key material.

Example fix

// before: sha256_password over plaintext, key not PEM
dsn := "user:pass@tcp(mysql57:3306)/db"
// -> "no Pem data found, data: ..."

// after: encrypt the transport
dsn := "user:pass@tcp(mysql57:3306)/db?tls=true"
Defensive patterns

Strategy: fallback

Validate before calling

// For sha256_password, use TLS or pin the key to skip PEM parsing.
mysql.RegisterServerPubKey("mysql57", serverKeyPEM)
dsn := "user:pass@tcp(host:3306)/db?tls=true" // or ?serverPubKey=mysql57

Type guard

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

Try / catch

if isNoPemDataSha256(err) {
    // switch to TLS, or pin serverPubKey, then retry.
}

Prevention

When it happens

Trigger: Authenticating with the sha256_password plugin (older MySQL 5.7 / MariaDB) over plaintext TCP without a pinned key, where the server's key payload is not valid PEM.

Common situations: sha256_password accounts behind a proxy that alters the auth payload; server/proxy incompatibility; MITM or corruption during the key exchange.

Related errors


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

Appendix: 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 03d76c7e07)