vitessio/vitess · error

could not get the original sql_mode on target: %v

Error message

could not get the original sql_mode on target: %v

What it means

setSQLMode first saves the target's current sql_mode so it can restore it later. It runs 'SELECT @@session.sql_mode' and requires exactly one row; if the query errors or returns an unexpected row count, this error is raised. The vreplication copy phase cannot proceed safely without capturing (then overriding) sql_mode.

Source

Thrown at go/vt/vttablet/tabletmanager/vreplication/vreplicator.go:664

	_, err := dbClient.Execute(fmt.Sprintf("set @@session.foreign_key_checks=%d", vr.originalFKCheckSetting))
	return err
}

func (vr *vreplicator) resetFKRestrictAfterCopy(dbClient *vdbClient) error {
	if !vr.needFKRestrict() {
		return nil
	}
	_, err := dbClient.Execute(fmt.Sprintf("set @@session.restrict_fk_on_non_standard_key=%d", vr.originalFKRestrict))
	return err
}

func (vr *vreplicator) setSQLMode(ctx context.Context, dbClient *vdbClient) (func(), error) {
	resetFunc := func() {}
	// First save the original SQL mode if we have not already done so
	if vr.originalSQLMode == "" {
		res, err := dbClient.Execute(getSQLModeQuery)
		if err != nil || len(res.Rows) != 1 {
			return resetFunc, fmt.Errorf("could not get the original sql_mode on target: %v", err)
		}
		vr.originalSQLMode = res.Named().Row().AsString("sql_mode", "")
	}

	// Create a callback function for resetting the original
	// SQL mode back at the end of the vreplication operation.
	// You should defer this callback wherever you call setSQLMode()
	resetFunc = func() {
		query := fmt.Sprintf(setSQLModeQueryf, vr.originalSQLMode)
		_, err := dbClient.Execute(query)
		if err != nil {
			log.Warn(fmt.Sprintf("Could not reset sql_mode on target using %s: %v", query, err))
		}
	}
	vreplicationSQLMode := SQLMode
	settings, _, err := vr.readSettings(ctx, dbClient)
	if err != nil {
		return resetFunc, err

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Check the embedded cause (%v): if it is blank, the query succeeded but returned zero rows — investigate any proxy/intermediary between tablet and mysqld.
  2. Verify tablet-to-MySQL connectivity and that mysqld is up; reconnect/restart the tablet if the session was lost.
  3. Run 'SELECT @@session.sql_mode' manually as the tablet's MySQL user to confirm access.
  4. Restart the workflow so setSQLMode runs on a fresh, healthy connection.
Defensive patterns

Strategy: retry

Validate before calling

// Verify the tablet's MySQL user can read session sql_mode:
// mysql -u <vtuser> -p -h <target> -e "SELECT @@session.sql_mode;"
// Expect exactly one row with one column.

Try / catch

res, err := dbClient.Execute(getSQLModeQuery)
if err != nil || len(res.Rows) != 1 {
	// reconnect or restart the stream; if err == nil, an intermediary
	// is mangling the result — check for proxies
	return resetFunc, retryAfterReconnect()
}

Prevention

When it happens

Trigger: Execute(getSQLModeQuery) returns an error (connection issue, permissions) OR len(res.Rows) != 1 — note a query error and empty result produce the same message, with err=nil in the empty-result case. Called by replicate and newClientConnection.

Common situations: Broken or just-reconnected MySQL connection; a proxy stripping or altering the SELECT result; mysqld restarted mid-copy; permission restrictions blocking @@session reads (rare, e.g. hardened setups).

Related errors


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