vitessio/vitess · warning
ErrNoSemiSync
ErrNoSemiSync
Error message
semi-sync plugin not loaded
What it means
ErrNoSemiSync is a sentinel error (errors.Is-comparable) indicating the semi-sync replication plugin (rpl_semi_sync_master/replica) is not loaded in mysqld. enableSemiSyncQuery and semiSyncReplicationStatusQuery return it when the semi-sync status variable doesn't exist because the plugin was never installed. Callers can use errors.Is to branch on it gracefully rather than treating it as a hard failure.
Source
Thrown at go/vt/mysqlctl/replication.go:1222
query := fmt.Sprintf("SHOW BINLOG EVENTS IN '%s' LIMIT 2", binlog)
qr, err := mysqld.FetchSuperQuery(ctx, query)
if err != nil {
return previousGtids, err
}
previousGtidsFound := false
for _, row := range qr.Named().Rows {
if row.AsString("Event_type", "") == "Previous_gtids" {
previousGtids = row.AsString("Info", "")
previousGtidsFound = true
}
}
if !previousGtidsFound {
return previousGtids, errors.New("GetPreviousGTIDs: previous GTIDs not found")
}
return previousGtids, nil
}
var ErrNoSemiSync = errors.New("semi-sync plugin not loaded")
func (mysqld *Mysqld) SemiSyncType(ctx context.Context) mysql.SemiSyncType {
if mysqld.semiSyncType == mysql.SemiSyncTypeUnknown {
mysqld.semiSyncType, _ = mysqld.SemiSyncExtensionLoaded(ctx)
}
return mysqld.semiSyncType
}
func (mysqld *Mysqld) enableSemiSyncQuery(ctx context.Context) (string, error) {
switch mysqld.SemiSyncType(ctx) {
case mysql.SemiSyncTypeSource:
return "SET GLOBAL rpl_semi_sync_source_enabled = %v, GLOBAL rpl_semi_sync_replica_enabled = %v", nil
case mysql.SemiSyncTypeMaster:
return "SET GLOBAL rpl_semi_sync_master_enabled = %v, GLOBAL rpl_semi_sync_slave_enabled = %v", nil
}
return "", ErrNoSemiSync
}
View on GitHub (pinned to 01a25a7d17)
Solutions
- Load the plugin: INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so' (and the master/source equivalent) on the mysqld instance.
- Check SemiSyncExtensionLoaded / SemiSyncType first and skip semi-sync setup when the plugin is absent.
- On MySQL 8.0.26+, account for the source/replica variable renaming — use the correct variable names for the server version.
- Compare with errors.Is(err, mysqlctl.ErrNoSemiSync) to treat absence as an expected, non-fatal condition.
Example fix
// before
_, err := mysqld.SemiSyncReplicationStatus(ctx)
if err != nil {
return err
}
// after
_, err := mysqld.SemiSyncReplicationStatus(ctx)
if errors.Is(err, mysqlctl.ErrNoSemiSync) {
log.Info("semi-sync plugin not loaded; continuing without semi-sync")
return nil
} else if err != nil {
return vterrors.Wrapf(err, "checking semi-sync status")
} Defensive patterns
Strategy: type-guard
Validate before calling
loaded, semiSyncType := mysqld.SemiSyncExtensionLoaded(ctx)
if !loaded {
log.Info("semi-sync extension not loaded; skipping semi-sync setup")
} Type guard
func isSemiSyncMissing(err error) bool {
return errors.Is(err, mysqlctl.ErrNoSemiSync)
} Try / catch
status, err := mysqld.SemiSyncReplicationStatus(ctx)
switch {
case errors.Is(err, mysqlctl.ErrNoSemiSync):
// expected: plugin absent, degrade gracefully
case err != nil:
return vterrors.Wrapf(err, "semi-sync status")
default:
_ = status
} Prevention
- INSTALL PLUGIN semisync (master/replica or source/replica variants) on all mysqlds that need semi-sync.
- On MySQL 8.0.26+ use the renamed rpl_semi_sync_source/replica variables and plugin names.
- Check SemiSyncExtensionLoaded before any semi-sync enable/status call.
- Always branch with errors.Is(err, mysqlctl.ErrNoSemiSync) instead of string matching.
When it happens
Trigger: Calling SemiSyncReplicationStatus (or code paths via enableSemiSyncQuery / semiSyncReplicationStatusQuery) on a mysqld without the semi-sync plugin loaded: the SHOW query for the semi-sync status variable returns no rows / unknown variable, and the function returns ErrNoSemiSync.
Common situations: MySQL 8.0.26+ renamed plugin variables (rpl_semi_sync_master_* -> rpl_semi_sync_source_*), leaving the plugin effectively unloaded under the old names; semi-sync plugin never installed via INSTALL PLUGIN; vanilla MySQL community builds without semi-sync compiled in.
Related errors
- no rpl_semi_sync_replica_status variable in mysql
- can't set semi-sync mode: %v; make sure plugins are loaded i
- Last_SQL_Error: ${LastSQL_Error}, Last_IO_Error: ${LastIO_Er
- GetPreviousGTIDs: previous GTIDs not found
- startPos.GTIDSet is wrong type - expected filePosGTID, got:
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/116c1cdb80eac723.
Report an issue: GitHub.