go-sql-driver/mysql · error
invalid dbname %q: %w
Error message
invalid dbname %q: %w
What it means
After isolating the database-name segment (between '/' and '?'), ParseDSN runs url.PathUnescape on it. If the segment contains malformed percent-encoding (e.g. '%ZZ', a lone '%' with no hex digits, or a truncated '%2'), PathUnescape fails and the driver wraps the underlying error as 'invalid dbname %q: %w' at dsn.go:465.
Source
Thrown at dsn.go:465
}
}
cfg.Net = dsn[j+1 : k]
}
// dbname[?param1=value1&...¶mN=valueN]
// Find the first '?' in dsn[i+1:]
for j = i + 1; j < len(dsn); j++ {
if dsn[j] == '?' {
if err = parseDSNParams(cfg, dsn[j+1:]); err != nil {
return
}
break
}
}
dbname := dsn[i+1 : j]
if cfg.DBName, err = url.PathUnescape(dbname); err != nil {
return nil, fmt.Errorf("invalid dbname %q: %w", dbname, err)
}
break
}
}
if !foundSlash && len(dsn) > 0 {
return nil, errInvalidDSNNoSlash
}
if err = cfg.normalize(); err != nil {
return nil, err
}
return
}
// parseDSNParams parses the DSN "query string"
// Values must be url.QueryEscape'edView on GitHub (pinned to c426bd9379)
Solutions
- URL-encode the database name with url.PathEscape when constructing the DSN.
- If the name genuinely contains '%', encode it as '%25'.
- Set cfg.DBName directly on a *mysql.Config and open via mysql.NewConnector(cfg) to bypass DSN parsing entirely.
Example fix
// before
dsn := fmt.Sprintf("user@tcp(host:3306)/%s", dbname) // dbname has '%'
// after
dsn := fmt.Sprintf("user@tcp(host:3306)/%s", url.PathEscape(dbname)) Defensive patterns
Strategy: validation
Validate before calling
// Confirm the dbname segment round-trips through PathUnescape.
func validDBNameSegment(seg string) bool {
_, err := url.PathUnescape(seg)
return err == nil
} Try / catch
if _, err := mysql.ParseDSN(dsn); err != nil {
var ue *url.EscapeError
if errors.As(err, &ue) || strings.Contains(err.Error(), "invalid dbname") {
// re-encode the dbname with url.PathEscape and rebuild
}
} Prevention
- Always url.PathEscape the database name when building a DSN.
- Set cfg.DBName directly and open via mysql.NewConnector to skip string parsing.
- Validate DSNs from env vars in a config loader before they reach sql.Open.
When it happens
Trigger: A DSN like 'user@tcp(host:3306)/my%ZZdb' or 'user@tcp(host:3306)/db%' where the dbname portion is not valid percent-encoding; a literal '%' in the name not encoded as '%25'.
Common situations: A database name containing a literal '%' or other special char that someone half-escaped; a templating system injected a raw symbol; URL-fragment accidentally included.
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 config name: {cfg.TLSConfig}
- invalid value / unknown server pub key name: {cfg.ServerPubK
AI-assisted analysis of go-sql-driver/mysql@c426bd9379 (2026-08-04).
Data as JSON: /data/errors/6caa65aeb686b798.json.
Report an issue: GitHub.