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

  1. Use a plain ASCII name that exactly matches a key added with mysql.RegisterServerPubKey.
  2. If the name must contain '%', encode it as %25.
  3. 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

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


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)