vitessio/vitess · error

FindReplicas: malformed addr

Error message

FindReplicas: malformed addr %v

What it means

FindReplicas parses the replica host addresses reported by `SHOW SLAVE STATUS`/processlist. Each address is passed to netutil.SplitHostPort, and if the address cannot be split into host and port, this error is thrown, aborting the whole lookup.

Solutions

  1. Check the replication topology output (`SHOW REPLICAS` / `SHOW SLAVE STATUS`) for malformed or missing addr values
  2. Fix the replica's report_host/report_port configuration so it reports a valid host:port
  3. Ensure replicas connect over TCP with a proper port rather than a local socket
  4. Re-run FindReplicas after correcting the replication configuration

Example fix

// before: replica reporting via unix socket
// after: in replica my.cnf
// report_host = 10.0.0.5
// report_port = 3306
Defensive patterns

Strategy: validation

Validate before calling

// validate replica addrs before calling FindReplicas
for _, a := range replicaAddrsFromStatus {
    if _, _, err := netutil.SplitHostPort(a); err != nil {
        log.Warnf("skipping malformed replica addr %q", a)
    }
}

Try / catch

addrs, err := mysqld.FindReplicas()
if err != nil && strings.Contains(err.Error(), "malformed addr") {
    log.Warn("replica reported malformed addr; check report_host config", slog.Any("error", err))
}

Prevention

When it happens

Trigger: Calling FindReplicas (directly or via GetReplicas) when a replica reports an addr that is not a valid host:port pair — e.g. empty or malformed host in SHOW REPLICAS / SHOW SLAVE STATUS output.

Common situations: Replica connected over a unix socket or reporting 'localhost' variants that escape the earlier localhost filter; unusual replication setups or network configurations where the reported addr lacks a port.

Understand the failure class

Related errors


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

Appendix: source

Thrown at go/vt/mysqlctl/replication.go:1159

	qr, err := mysqld.FetchSuperQuery(ctx, "SHOW PROCESSLIST")
	if err != nil {
		return nil, err
	}
	addrs := make([]string, 0, 32)
	for _, row := range qr.Rows {
		// Check for prefix, since it could be "Binlog Dump GTID".
		if strings.HasPrefix(row[colCommand].ToString(), binlogDumpCommand) {
			host := row[colClientAddr].ToString()
			if host == "localhost" {
				// If we have a local binlog streamer, it will
				// show up as being connected
				// from 'localhost' through the local
				// socket. Ignore it.
				continue
			}
			host, _, err = netutil.SplitHostPort(host)
			if err != nil {
				return nil, fmt.Errorf("FindReplicas: malformed addr %v", err)
			}
			var ips []string
			ips, err = net.LookupHost(host)
			if err != nil {
				return nil, fmt.Errorf("FindReplicas: LookupHost failed %v", err)
			}
			addrs = append(addrs, ips...)
		}
	}

	return addrs, nil
}

// GetGTIDMode gets the GTID mode for the server
func (mysqld *Mysqld) GetGTIDMode(ctx context.Context) (string, error) {
	conn, err := getPoolReconnect(ctx, mysqld.dbaPool)
	if err != nil {
		return "", err

View on GitHub (pinned to 01a25a7d17)