go-sql-driver/mysql · error
invalid value for server pub key name
Error message
invalid value for server pub key name: %v
What it means
The 'serverPubKey' DSN parameter names a server public key registered via mysql.RegisterServerPubKey (used for sha256_password/caching_sha2_password key exchange). Its value is url.QueryUnescape'd; a malformed percent-escape in the value produces this error wrapping the unescape failure.
Solutions
- Use a plain ASCII name that exactly matches a key added with mysql.RegisterServerPubKey.
- If the name must contain '%', encode it as %25.
- Avoid special characters in registered public-key names.
Example fix
// before
sql.Open("mysql", "user@tcp(127.0.0.1:3306)/db?serverPubKey=my%key")
// after
sql.Open("mysql", "user@tcp(127.0.0.1:3306)/db?serverPubKey=my%25key") Defensive patterns
Strategy: validation
Validate before calling
// Ensure the value query-unescapes cleanly.
import "net/url"
if _, err := url.QueryUnescape(pubKeyName); err != nil {
return err
} Type guard
null
Try / catch
// serverPubKey issues surface at DSN parse time; validate the DSN first.
if _, err := mysql.ParseDSN(dsn); err != nil {
return err
} Prevention
- Keep serverPubKey names to plain ASCII identifiers.
- Register the key (RegisterServerPubKey) with the exact name used in the DSN.
- Percent-escape any generated name with url.QueryEscape.
When it happens
Trigger: A DSN like '?serverPubKey=%ZZ' or any value where '%' is not followed by two hex digits, and the value is meant to reference a registered public-key name.
Common situations: Rare, since the value is usually a plain ASCII name. Occurs when the name is generated or escaped incorrectly, or a stray '%' is introduced.
Related errors
- invalid value for TLS config name
- key ' ' is reserved
- invalid connectionAttributes value
- invalid dbname
- invalid timeTruncate value
AI-assisted analysis of go-sql-driver/mysql@03d76c7e07 (2026-08-07).
Data as JSON: /api/errors/c610f430788a64bd.
Report an issue: GitHub.
Appendix: source
Thrown at dsn.go:632
case "readTimeout":
cfg.ReadTimeout, err = time.ParseDuration(value)
if err != nil {
return
}
// Reject read-only connections
case "rejectReadOnly":
var isBool bool
cfg.RejectReadOnly, isBool = readBool(value)
if !isBool {
return errors.New("invalid bool value: " + value)
}
// Server public key
case "serverPubKey":
name, err := url.QueryUnescape(value)
if err != nil {
return fmt.Errorf("invalid value for server pub key name: %v", err)
}
cfg.ServerPubKey = name
// Strict mode
case "strict":
panic("strict mode has been removed. See https://github.com/go-sql-driver/mysql/wiki/strict-mode")
// Dial Timeout
case "timeout":
cfg.Timeout, err = time.ParseDuration(value)
if err != nil {
return
}
// TLS-Encryption
case "tls":
boolValue, isBool := readBool(value)
if isBool {View on GitHub (pinned to 03d76c7e07)