vitessio/vitess · error

could not set the permissive sql_mode on target using %s: %v

Error message

could not set the permissive sql_mode on target using %s: %v

What it means

After saving the original sql_mode, setSQLMode applies a permissive mode (vreplicationSQLMode) so schema DDL from the source can be replayed verbatim on the target (e.g. to bypass ONLY_FULL_GROUP_BY / STRICT_* rejections). If the SET SESSION sql_mode statement fails, this error wraps the executed query and MySQL error.

Source

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

		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
	}
	if settings.WorkflowType == binlogdatapb.VReplicationWorkflowType_OnlineDDL {
		vreplicationSQLMode = StrictSQLMode
	}

	// Now set it to a permissive mode that will allow us to recreate
	// any database object that exists on the source in full on the
	// target
	query := fmt.Sprintf(setSQLModeQueryf, vreplicationSQLMode)
	if _, err := dbClient.Execute(query); err != nil {
		return resetFunc, fmt.Errorf("could not set the permissive sql_mode on target using %s: %v", query, err)
	}

	return resetFunc, nil
}

// throttlerAppName returns the app name to be used by throttlerClient for this particular workflow
// example results:
//   - "vreplication" for most flows
//   - "vreplication:online-ddl" for online ddl flows.
//     Note that with such name, it's possible to throttle
//     the workflow by either "vreplication" and/or "online-ddl"
//     This is useful when we want to throttle all migrations. We throttle "online-ddl".
func (vr *vreplicator) throttlerAppName() string {
	names := []string{vr.WorkflowName, throttlerapp.VReplicationName.String()}
	if vr.WorkflowType == int32(binlogdatapb.VReplicationWorkflowType_OnlineDDL) {
		names = append(names, throttlerapp.OnlineDDLName.String())
	}
	return throttlerapp.Concatenate(names...)

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Read the wrapped MySQL error; if the connection died, restart the tablet/workflow to re-establish a session.
  2. Confirm the tablet's MySQL user may SET SESSION sql_mode (no restrictions via proxies or POLICY-layer blocks).
  3. Check for vitess-to-vitess replication targets: ensure the target tablet does not forbid session variable changes.
  4. Re-run the workflow after the connection/session issue is resolved — sql_mode is set per session.
Defensive patterns

Strategy: retry

Validate before calling

// Confirm SET SESSION sql_mode works for the tablet user:
// mysql -u <vtuser> -h <target> -e "SET @@session.sql_mode='NO_ENGINE_SUBSTITUTION'; SELECT 1;"

Try / catch

if _, err := dbClient.Execute(query); err != nil {
	log.Warn("failed to set permissive sql_mode", slog.String("query", query), slog.Any("error", err))
	// retry on a fresh connection; check proxy/intermediary if it keeps failing
}

Prevention

When it happens

Trigger: 'SET @@session.sql_mode = ...' fails due to a dead connection, mysqld read-only session restrictions, or a proxy that disallows session-variable SETs. Called by replicate and newClientConnection during copy-phase setup.

Common situations: Vitess-to-Vitess VReplication targets that reject session variable changes; connection dropped between the SELECT and the SET; hardened MySQL profiles or intermediaries blocking SET sql_mode.

Related errors


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