vitessio/vitess · error
session variable %q is not allowed
Error message
session variable %q is not allowed
What it means
ValidateSessionVariable checks a DDL strategy session variable name against a regexp and then against a denylist (deniedSessionVariables). This error means the variable name is syntactically valid but is explicitly forbidden (e.g. variables Vitess must control itself during online schema changes, like foreign_key_checks or sql_log_bin). The variable's value is irrelevant; the name itself is rejected case-insensitively.
Source
Thrown at go/vt/schema/ddl_strategy.go:216
// IsSingletonTable checks if strategy options include --singleton-table
func (setting *DDLStrategySetting) IsSingletonTable() bool {
return setting.hasFlag(singletonTableFlag)
}
// IsAllowZeroInDateFlag checks if strategy options include --allow-zero-in-date
func (setting *DDLStrategySetting) IsAllowZeroInDateFlag() bool {
return setting.hasFlag(allowZeroInDateFlag)
}
// ValidateSessionVariable ensures a variable name is safe to interpolate as a
// MySQL system variable identifier.
func ValidateSessionVariable(variable SessionVariable) error {
if !sessionVariableNameRegexp.MatchString(variable.Name) {
return fmt.Errorf("invalid session variable name: %q", variable.Name)
}
if _, ok := deniedSessionVariables[strings.ToLower(variable.Name)]; ok {
return fmt.Errorf("session variable %q is not allowed", variable.Name)
}
return nil
}
// ValidateSessionVariables validates variable names and rejects
// case-insensitive duplicates.
func ValidateSessionVariables(variables []SessionVariable) error {
seen := map[string]struct{}{}
for _, variable := range variables {
if err := ValidateSessionVariable(variable); err != nil {
return err
}
normalizedName := strings.ToLower(variable.Name)
if _, ok := seen[normalizedName]; ok {
return fmt.Errorf("duplicate session variable name: %q", variable.Name)
}
seen[normalizedName] = struct{}{}
}View on GitHub (pinned to 01a25a7d17)
Solutions
- Remove the denied variable from the --session-variable list in the DDL strategy.
- Check the deniedSessionVariables map in go/vt/schema/ddl_strategy.go to see which names are forbidden.
- Use an allowed alternative: e.g. rely on the DDL strategy's own options instead of disabling foreign_key_checks manually.
Example fix
// before
dl := schema.ParseDDLStrategy("online --session-variable foreign_key_checks=0")
// after
dl := schema.ParseDDLStrategy("online") Defensive patterns
Strategy: validation
Validate before calling
for _, v := range variables {
if schema.ValidateSessionVariable(schema.SessionVariable{Name: v.Name, Value: v.Value}) != nil {
// drop or fix this variable before building the strategy
}
} Try / catch
if err := schema.ValidateSessionVariables(vars); err != nil {
return fmt.Errorf("rejecting DDL strategy: %w", err)
} Prevention
- Keep a copy of the denylist in tooling that builds --session-variable flags.
- Never add variables Vitess owns (foreign_key_checks, sql_log_bin, unique_checks).
- Unit-test any code that composes DDL strategy strings.
When it happens
Trigger: Calling ParseDDLStrategy or SessionVariables() with a --session-variable option whose name is in the denied set, e.g. --ddl-strategy="online --session-variable foreign_key_checks=0". Validation runs via ValidateSessionVariables -> ValidateSessionVariable.
Common situations: Users porting plain-MySQL ALTER workflows to Vitess online DDL and disabling server-controlled settings (foreign_key_checks, unique_checks, sql_log_bin) that Vitess manages itself; copy-pasted MySQL client commands including these variables.
Related errors
- Unknown online DDL strategy: '%v'
- duplicate session variable name: %q
- BeforeSchema differs
- AfterSchema differs
- --force-cut-over-after is only valid in 'vitess' strategy. F
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/c90110886833ec83.
Report an issue: GitHub.