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
- Read the wrapped MySQL error; if the connection died, restart the tablet/workflow to re-establish a session.
- Confirm the tablet's MySQL user may SET SESSION sql_mode (no restrictions via proxies or POLICY-layer blocks).
- Check for vitess-to-vitess replication targets: ensure the target tablet does not forbid session variable changes.
- 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
- Allow SET SESSION sql_mode for the replication user.
- Avoid vitess-to-vitess targets or proxies that block session variable SETs.
- Reconnect and retry on connection-loss error codes.
- Keep source and target MySQL modes documented so DDL replay expectations are clear.
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
- could not get the original sql_mode on target: %v
- direct DDL is disabled
- online DDL is disabled
- Foreign key found
- RENAME clause found
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/73ec4e422050db65.
Report an issue: GitHub.