gastownhall/beads · error

failed to open MySQL connection: %w

Error message

failed to open MySQL connection: %w

What it means

runDoltServerDiagnostics builds a MySQL DSN and calls sql.Open; a non-nil error (invalid DSN/driver problem) is wrapped with this message. Note sql.Open rarely contacts the network — most runtime failures surface at ping (error 526).

Source

Thrown at cmd/bd/doctor/perf_dolt.go:135

		user = cfg.GetDoltServerUser()
		tls = cfg.GetDoltServerTLS()
		password = cfg.GetDoltServerPasswordForPort(port)
	}

	dsn := doltutil.ServerDSN{
		Host:     host,
		Port:     port,
		User:     user,
		Password: password,
		Database: dbName,
		TLS:      tls,
	}.String()

	// Measure connection time
	start := time.Now()
	db, err := sql.Open("mysql", dsn)
	if err != nil {
		return fmt.Errorf("failed to open MySQL connection: %w", err)
	}
	defer db.Close()

	// Set connection pool settings
	db.SetMaxOpenConns(5)
	db.SetMaxIdleConns(2)

	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
	defer cancel()
	if err := db.PingContext(ctx); err != nil {
		return fmt.Errorf("failed to ping server: %w", err)
	}
	metrics.ConnectionTime = time.Since(start).Milliseconds()

	// Run all diagnostics
	return runDoltDiagnosticQueries(ctx, db, metrics)
}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Check the composed DSN in the error context for malformed format or unescaped characters (use url.QueryEscape for password/special chars)
  2. Verify host/port/dbname values in the Dolt server config
  3. Ensure the go-sql-driver/mysql driver is imported for side-effect registration

Example fix

// before
dsn := fmt.Sprintf("root:%s@tcp(%s:%d)/%s", pass, host, port, db) // unescaped pass with '@' breaks DSN
// after
dsn := fmt.Sprintf("root:%s@tcp(%s:%d)/%s", url.QueryEscape(pass), host, port, db)
Defensive patterns

Strategy: validation

Validate before calling

func validDSN(user, pass, host string, port int, db string) bool {
    _, err := mysql.ParseDSN(fmt.Sprintf("%s:%s@tcp(%s:%d)/%s", user, url.QueryEscape(pass), host, port, db))
    return err == nil
}

Try / catch

var opErr *net.OpError
if errors.As(err, &opErr) { log.Printf("DSN/network error: %v", opErr) }

Prevention

When it happens

Trigger: sql.Open("mysql", dsn) returns an error, typically a malformed DSN string (bad format, invalid params) or the mysql driver not being registered.

Common situations: Wrong host/port/password characters needing DSN escaping; config producing a DSN like 'user:pass@tcp(host:port)/db' with missing separators; driver import removed.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/40906c9fba7928a8. Report an issue: GitHub.