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

  1. Remove the denied variable from the --session-variable list in the DDL strategy.
  2. Check the deniedSessionVariables map in go/vt/schema/ddl_strategy.go to see which names are forbidden.
  3. 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

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


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