vitessio/vitess · error

The receiver ReplicationStatus contained a Mysql56GTIDSet in

Error message

The receiver ReplicationStatus contained a Mysql56GTIDSet in its relay log, but a replica's ReplicationStatus is of another flavor. This should never happen.

What it means

FindErrantGTIDs computes errant transactions by diffing the receiver's Mysql56GTIDSet relay-log GTID set against GTID sets from other replica positions. It panics if any otherPositions entry holds a GTIDSet of a different flavor (e.g. MariaDB GTIDSet) while the receiver holds a Mysql56GTIDSet, since GTID sets of different flavors cannot be compared. This guards an invariant that all compared statuses come from the same GTID flavor.

Source

Thrown at go/mysql/replication/replication_status.go:212

// provided as a list of Positions. This method only works if the flavor for all retrieved Positions is MySQL.
// The result is returned as a Mysql56GTIDSet, each of whose elements is a found errant GTID.
// This function is best effort in nature. If it marks something as errant, then it is for sure errant. But there may be cases of errant GTIDs, which aren't caught by this function.
func FindErrantGTIDs(position Position, sourceUUID SID, otherPositions []Position) (Mysql56GTIDSet, error) {
	if len(otherPositions) == 0 {
		// If there is nothing to compare this replica against, then we must assume that its GTID set is the correct one.
		return nil, nil
	}

	gtidSet, ok := position.GTIDSet.(Mysql56GTIDSet)
	if !ok {
		return nil, errors.New("errant GTIDs can only be computed on the MySQL flavor")
	}

	otherSets := make([]Mysql56GTIDSet, 0, len(otherPositions))
	for _, pos := range otherPositions {
		otherSet, ok := pos.GTIDSet.(Mysql56GTIDSet)
		if !ok {
			panic("The receiver ReplicationStatus contained a Mysql56GTIDSet in its relay log, but a replica's ReplicationStatus is of another flavor. This should never happen.")
		}
		otherSets = append(otherSets, otherSet)
	}

	// Copy set for final diffSet so we don't mutate receiver.
	diffSet := make(Mysql56GTIDSet, len(gtidSet))
	for sid, intervals := range gtidSet {
		if sid == sourceUUID {
			continue
		}
		diffSet[sid] = intervals
	}

	for _, otherSet := range otherSets {
		diffSet = diffSet.Difference(otherSet)
	}

	if len(diffSet) == 0 {

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Verify all tablets in the keyspace use the same GTID mode (mysql56) via SHOW VARIABLES LIKE 'gtid_mode' / vitess init flags.
  2. Ensure every ReplicationStatus passed to FindErrantGTIDs comes from MySQL56-flavor tablets; filter or convert otherPositions first.
  3. Re-initialize mismatched tablets with the correct -init_gtid_mode / flavor configuration.

Example fix

// before
errant, err := status.FindErrantGTIDs(otherStatuses) // otherStatuses contains a MariaDB-flavor status
// after
for i, st := range otherStatuses {
    if _, ok := st.RelayLogPosition.GTIDSet.(mysql.Mysql56GTIDSet); !ok {
        return fmt.Errorf("status %d is not MySQL56 GTID flavor; skipping", i)
    }
}
errant, err := status.FindErrantGTIDs(otherStatuses)
Defensive patterns

Strategy: type-guard

Validate before calling

for _, pos := range otherPositions {
    if _, ok := pos.GTIDSet.(mysql.Mysql56GTIDSet); !ok {
        return fmt.Errorf("cannot compare GTID flavors: %T", pos.GTIDSet)
    }
}

Type guard

func isMysql56GTIDSet(s mysql.GTIDSet) bool {
    _, ok := s.(mysql.Mysql56GTIDSet)
    return ok
}

Try / catch

defer func() { if r := recover(); r != nil { err = fmt.Errorf("FindErrantGTIDs flavor mismatch: %v", r) } }()

Prevention

When it happens

Trigger: Calling FindErrantGTIDs or findErrantGTIDs with a mix of ReplicationStatus values where the receiver uses MySQL 5.6 GTIDs but at least one otherPositions entry carries a non-MySQL56 GTIDSet (e.g. MariaDB flavor).

Common situations: Cluster with mixed MySQL and MariaDB replicas; reparenting/emergency operations (EmergencyReparentShard) run across a keyspace where one tablet was initialized with a different GTID mode; config drift where some tablets run with gtid_mode=OFF/MariaDB style.

Related errors


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