argoproj/argo-workflows · error

invalid MySQL config options: %w

Error message

invalid MySQL config options: %w

What it means

buildMySQLConfig round-trips the constructed mysql.Config through mysql.ParseDSN(mysqlCfg.FormatDSN()) so driver-level options are interpreted at the driver layer rather than sent to the server as SET statements. If FormatDSN produces a DSN that go-sql-driver/mysql's ParseDSN rejects, this 'invalid MySQL config options' error is returned wrapping the parse error.

Source

Thrown at util/sqldb/sqldb.go:279

	mysqlCfg := mysql.NewConfig()
	mysqlCfg.User = username
	mysqlCfg.Passwd = password
	mysqlCfg.Net = "tcp"
	mysqlCfg.Addr = cfg.GetHostname()
	mysqlCfg.DBName = cfg.Database
	mysqlCfg.ParseTime = true
	mysqlCfg.AllowNativePasswords = true // Required for MariaDB which uses mysql_native_password by default
	mysqlCfg.Params = cfg.Options
	mysqlCfg.Timeout = connectTimeout
	// cfg.Options mixes driver-level DSN options (tls, readTimeout, ...) with
	// server system variables. NewConnector consumes the config directly, and the
	// driver only interprets driver-level options when parsing a DSN — left in
	// Params they would be sent to the server as SET statements instead (e.g.
	// leaving TLS disabled). Round-trip through FormatDSN/ParseDSN so options are
	// interpreted the same way DSN-opened sessions always interpreted them.
	parsedCfg, err := mysql.ParseDSN(mysqlCfg.FormatDSN())
	if err != nil {
		return nil, fmt.Errorf("invalid MySQL config options: %w", err)
	}
	return parsedCfg, nil
}

func createMySQLDBSessionWithCreds(cfg *config.MySQLConfig, persistPool *config.ConnectionPool, username, password string, connectTimeout time.Duration) (db.Session, error) {
	mysqlCfg, err := buildMySQLConfig(cfg, username, password, connectTimeout)
	if err != nil {
		return nil, err
	}

	// Wrap the MySQL connector so Connect (dial + handshake read) is bounded by
	// connectTimeout, protecting against a half-open server the same way lib/pq's
	// connect_timeout protects PostgreSQL.
	connector, err := mysql.NewConnector(mysqlCfg)
	if err != nil {
		return nil, fmt.Errorf("failed to create mysql connector: %w", err)
	}
	wrapped := &timeoutConnector{Connector: connector, timeout: connectTimeout}

View on GitHub (pinned to 35bff19146)

Solutions

  1. Look at the wrapped ParseDSN error text — it names the offending DSN key or value; remove or correct that key in the MySQL config.
  2. Validate each MySQL configmap field against the documented MySQLConfig schema; put only go-sql-driver-supported parameters in params/driver options.
  3. If you need custom driver options, confirm they are valid DSN parameters for your go-sql-driver version (e.g. tls=true, allowNativePasswords).
  4. Test the equivalent DSN directly with mysql.ParseDSN or by connecting with the mysql CLI using the same options.

Example fix

// before
mysql:
  params:
    sslmode: require     # not a go-sql-driver option -> ParseDSN error
// after
mysql:
  options:
    tls: true            # driver-level option, accepted by ParseDSN
Defensive patterns

Strategy: validation

Validate before calling

// sanity-check config before calling CreateDBSessionWithCreds
if cfg.Host == "" || cfg.Port == 0 { return errors.New("mysql host/port required") }
for k := range cfg.Params {
    if !allowedDSNParams[k] { return fmt.Errorf("unsupported mysql param: %s", k) }
}

Try / catch

session, err := CreateDBSessionWithCreds(ctx)
if err != nil && strings.Contains(err.Error(), "invalid MySQL config options") {
    // log full wrapped error; fail fast with actionable config message
    logger.Error(ctx, "mysql config rejected by driver", err)
    return err
}

Prevention

When it happens

Trigger: createMySQLDBSessionWithCreds calls buildMySQLConfig with a MySQLConfig whose fields (address, params, timeout values, driver options) produce an unparseable DSN — e.g. invalid parameter names/values in Params, malformed address, or an option ParseDSN cannot interpret.

Common situations: Users add arbitrary keys under the MySQL 'params' or driver-options section of the configmap that go-sql-driver does not accept; bad time.Duration values for timeouts; copy-pasted DSN fragments placed into structured config fields; version upgrades where go-sql-driver tightened option validation.

Related errors


AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03). Data as JSON: /api/errors/6cd95d05c4226f22. Report an issue: GitHub.