vitessio/vitess · error

can't dial mysqlctld: %v

Error message

can't dial mysqlctld: %v

What it means

Mysqld.RunMysqlUpgrade was asked to execute remotely on a mysqlctld server (socketFile set), but the mysqlctl RPC client could not dial that server over the unix socket. The upgrade request never reached mysqlctld.

Source

Thrown at go/vt/mysqlctl/mysqld.go:417

	}
	ver.Patch, err = strconv.Atoi(string(v[3]))
	if err != nil {
		return flavor, ver, fmt.Errorf("could not parse server version from: %s", version)
	}

	return
}

// RunMysqlUpgrade will run the mysql_upgrade program on the current
// install.  Will be called only when mysqld is running with no
// network and no grant tables.
func (mysqld *Mysqld) RunMysqlUpgrade(ctx context.Context) error {
	// Execute as remote action on mysqlctld if requested.
	if socketFile != "" {
		log.Info(fmt.Sprintf("executing Mysqld.RunMysqlUpgrade() remotely via mysqlctld server: %v", socketFile))
		client, err := mysqlctlclient.New(ctx, "unix", socketFile)
		if err != nil {
			return fmt.Errorf("can't dial mysqlctld: %v", err)
		}
		defer client.Close()
		return client.RunMysqlUpgrade(ctx)
	}

	if mysqld.capabilities.hasMySQLUpgradeInServer() {
		log.Warn("MySQL version has built-in upgrade, skipping RunMySQLUpgrade")
		return nil
	}

	// Since we started mysql with --skip-grant-tables, we should
	// be able to run mysql_upgrade without any valid user or
	// password. However, mysql_upgrade executes a 'flush
	// privileges' right in the middle, and then subsequent
	// commands fail if we don't use valid credentials. So let's
	// use dba credentials.
	params, err := mysqld.dbcfgs.DbaConnector().MysqlParams()
	if err != nil {

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Confirm mysqlctld is running and listening on the configured unix socket (`ls -l <socketFile>`)
  2. Correct the --mysqlctl_remote_socket flag value
  3. Restart mysqlctld, then retry the upgrade
  4. If you don't need remote execution, unset the socket flag so RunMysqlUpgrade runs locally

Example fix

// before: remote mode with stale socket
return mysqld.RunMysqlUpgrade(ctx) // socketFile points to dead server
// after: restart mysqlctld first
if _, err := os.Stat(socketFile); err != nil {
    log.Warning("mysqlctld socket missing, running upgrade locally")
}
return mysqld.RunMysqlUpgrade(ctx)
Defensive patterns

Strategy: retry

Validate before calling

if _, err := os.Stat(socketFile); err != nil {
    return fmt.Errorf("mysqlctld socket %s missing; is mysqlctld running?", socketFile)
}

Try / catch

err := mysqld.RunMysqlUpgrade(ctx)
if strings.Contains(err.Error(), "can't dial mysqlctld") {
    // wait for mysqlctld and retry once
    time.Sleep(2 * time.Second)
    err = mysqld.RunMysqlUpgrade(ctx)
}

Prevention

When it happens

Trigger: Calling Mysqld.RunMysqlUpgrade while the mysqlctl remote-action socket (-mysqlctl_remote_socket / socketFile) is configured and mysqlctld is not running, has exited, or the socket path is wrong.

Common situations: mysqlctld crashed or was restarted between actions; wrong socket file path in flags; permission denied on /tmp socket; using remote-action mode without launching mysqlctld.

Understand the failure class

Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.

Related errors


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/84fd436c1316115b. Report an issue: GitHub.