go-sql-driver/mysql · error
invalid value / unknown config name: {cfg.TLSConfig}
Error message
invalid value / unknown config name: {cfg.TLSConfig} What it means
normalize() resolves cfg.TLSConfig against the reserved words 'false'/'', 'true', 'skip-verify', 'preferred', then falls back to the registry populated by RegisterTLSConfig. If the key is not reserved and not registered, getTLSConfigClone returns nil and the driver returns 'invalid value / unknown config name' at dsn.go:210.
Source
Thrown at dsn.go:210
} else if cfg.Net == "tcp" {
cfg.Addr = ensureHavePort(cfg.Addr)
}
if cfg.TLS == nil {
switch cfg.TLSConfig {
case "false", "":
// don't set anything
case "true":
cfg.TLS = &tls.Config{}
case "skip-verify":
cfg.TLS = &tls.Config{InsecureSkipVerify: true}
case "preferred":
cfg.TLS = &tls.Config{InsecureSkipVerify: true}
cfg.AllowFallbackToPlaintext = true
default:
cfg.TLS = getTLSConfigClone(cfg.TLSConfig)
if cfg.TLS == nil {
return errors.New("invalid value / unknown config name: " + cfg.TLSConfig)
}
}
}
if cfg.TLS != nil && cfg.TLS.ServerName == "" && !cfg.TLS.InsecureSkipVerify {
host, _, err := net.SplitHostPort(cfg.Addr)
if err == nil {
cfg.TLS.ServerName = host
}
}
if cfg.ServerPubKey != "" {
cfg.pubKey = getServerPubKey(cfg.ServerPubKey)
if cfg.pubKey == nil {
return errors.New("invalid value / unknown server pub key name: " + cfg.ServerPubKey)
}
}
View on GitHub (pinned to c426bd9379)
Solutions
- Call mysql.RegisterTLSConfig('custom', &tls.Config{...}) before sql.Open/ParseDSN, in the same process.
- Verify the key string matches exactly (case, spelling) between RegisterTLSConfig and the DSN.
- Use a built-in mode ('true', 'skip-verify', 'preferred') instead of a custom key when you do not need a custom tls.Config.
- If you set cfg.TLS directly on the Config, the TLSConfig-name lookup is skipped entirely.
Example fix
// before
db, _ := sql.Open("mysql", "user@tcp(host:3306)/db?tls=custom")
// after
mysql.RegisterTLSConfig("custom", &tls.Config{RootCAs: rootCAs, Certificates: certs})
db, _ := sql.Open("mysql", "user@tcp(host:3306)/db?tls=custom") Defensive patterns
Strategy: validation
Validate before calling
// Verify the key is registered (or a reserved word) before opening.
func tlsKeyKnown(key string) bool {
switch key { case "", "false", "true", "skip-verify", "preferred": return true }
// reflect on the registry is not exported; simplest: keep your own set of registered keys
return false // replace with your app's tracking of registered names
} Try / catch
if _, err := mysql.ParseDSN(dsn); err != nil && strings.Contains(err.Error(), "unknown config name") {
// register the TLS config under the right key, then retry
} Prevention
- Register every custom TLS config in a single init() that runs before any sql.Open.
- Centralize DSN/TLS construction in one package so registration order is obvious.
- Prefer the built-in 'preferred'/'skip-verify'/'true' modes when a custom tls.Config is not required.
When it happens
Trigger: A DSN with '?tls=custom' without a prior mysql.RegisterTLSConfig('custom', &tls.Config{...}) call; or the key was registered under a different name, or deregistered before connect.
Common situations: TLS registration code in main.go but the DSN is parsed earlier (init/test); typo between the RegisterTLSConfig key and the DSN; trying to register a reserved word ('true'/'skip-verify'/'preferred') which RegisterTLSConfig rejects; registration in a different process than the one opening the connection.
Related errors
- invalid DSN: did you forget to escape a param value?
- invalid DSN: missing the slash separating the database name
- default addr for network '{cfg.Net}' unknown
- invalid value / unknown server pub key name: {cfg.ServerPubK
- invalid bool value: {value}
AI-assisted analysis of go-sql-driver/mysql@c426bd9379 (2026-08-04).
Data as JSON: /data/errors/c69fdd0bbeba1e72.json.
Report an issue: GitHub.