argoproj/argo-workflows · error

failed to create mysql connector: %w

Error message

failed to create mysql connector: %w

What it means

Returned when mysql.NewConnector(mysqlCfg) fails while building a MySQL database session. mysql.NewConnector rarely fails — it validates the mysql.Config — so this indicates the driver rejected the config object itself (e.g. invalid Net/Addr combination or nil config) before any network dial is attempted. The connector is subsequently wrapped in a timeoutConnector so Connect() is bounded by connectTimeout.

Source

Thrown at util/sqldb/sqldb.go:295

	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}

	// Create traced *sql.DB using otelsql
	sqlDB := otelsql.OpenDB(wrapped, otelSQLOptions(semconv.DBSystemNameMySQL, cfg.Database)...)

	// Wrap with upper/db
	session, err := mysqladp.New(sqlDB)
	if err != nil {
		sqlDB.Close()
		return nil, fmt.Errorf("failed to create upper/db session: %w", err)
	}

	session = ConfigureDBSession(session, persistPool)

	// this is needed to make MySQL run in a Golang-compatible UTF-8 character set.
	_, err = session.SQL().Exec("SET NAMES 'utf8mb4'")
	if err != nil {

View on GitHub (pinned to 35bff19146)

Solutions

  1. Inspect the wrapped error and the mysql.Config fields (Net, Addr) built from your MySQLConfig; ensure a valid protocol/address pair (tcp:host:port or unix:/path/to/socket).
  2. Set host and port explicitly in the mysql section of the controller config and retry.
  3. If running in k8s, confirm the configmap mounted for the controller has the mysql block populated and not empty.
  4. Update go-sql-driver/mysql if a config combination previously valid now fails validation.

Example fix

// before (empty address)
mysql:
  host: ""
// after
mysql:
  host: mysql.mysql.svc
  port: 3306
Defensive patterns

Strategy: validation

Validate before calling

if cfg == nil || cfg.Host == "" { return errors.New("mysql config incomplete: host is required") }
// valid Net combos: "tcp","tcp4","tcp6","unix","cloudsql"

Try / catch

session, err := CreateDBSessionWithCreds(ctx)
if err != nil && strings.Contains(err.Error(), "failed to create mysql connector") {
    logger.Error(ctx, "mysql connector construction failed — check Net/Addr config", err)
    return err
}

Prevention

When it happens

Trigger: createMySQLDBSessionWithCreds calls mysql.NewConnector with a *mysql.Config that go-sql-driver considers invalid — practically only reachable with an empty/nil config or invalid Net ('tcp','unix','cloudsql' rules violated), since DSN-level issues were caught earlier by ParseDSN round-trip.

Common situations: Programmatic callers constructing MySQLConfig with a blank address or unknown network type; custom integrations calling CreateDBSessionWithCreds with zero-valued config; misconfigured 'protocol'/'address' pairs (e.g. unix socket path that is empty).

Related errors


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