vitessio/vitess · error
tenant column name not defined in multi-tenant spec
Error message
tenant column name not defined in multi-tenant spec
What it means
When a tenant clause is being built, the multi-tenant spec's tenant_id_column_name must be non-empty; an empty name means the filter expression cannot reference the tenant column. This error is raised after the MultiTenantSpec existence check (234) but before parsing the tenant id value.
Source
Thrown at go/vt/vtctl/workflow/utils.go:850
Type: sqlparser.WhereClause,
Expr: filter,
}
}
}
func getTenantClause(vrOptions *vtctldatapb.WorkflowOptions,
targetVSchema *vindexes.KeyspaceSchema, parser *sqlparser.Parser,
) (*sqlparser.Expr, error) {
if vrOptions.TenantId == "" {
return nil, nil
}
if targetVSchema == nil || targetVSchema.MultiTenantSpec == nil {
return nil, errors.New("target keyspace not defined, or it does not have multi-tenant spec")
}
tenantColumnName := targetVSchema.MultiTenantSpec.TenantIdColumnName
tenantColumnType := targetVSchema.MultiTenantSpec.TenantIdColumnType
if tenantColumnName == "" {
return nil, errors.New("tenant column name not defined in multi-tenant spec")
}
var tenantId string
switch tenantColumnType {
case querypb.Type_INT64:
_, err := strconv.Atoi(vrOptions.TenantId)
if err != nil {
return nil, fmt.Errorf("tenant id is not a valid int: %s", vrOptions.TenantId)
}
tenantId = vrOptions.TenantId
case querypb.Type_VARCHAR:
tenantId = sqltypes.EncodeStringSQL(vrOptions.TenantId)
default:
return nil, fmt.Errorf("unsupported tenant column type: %s", tenantColumnType)
}
stmt, err := parser.Parse(fmt.Sprintf("select * from t where %s = %s", sqlescape.EscapeID(tenantColumnName), tenantId))
if err != nil {View on GitHub (pinned to 01a25a7d17)
Solutions
- Set tenant_id_column_name in the target keyspace's multi_tenant_spec and re-apply the vschema
- Confirm the tenant column actually exists in the replicated tables
- Remove --tenant-id if tenant filtering is not needed
Example fix
// before
{"multi_tenant_spec":{"tenant_id_column_type":"INT64"}}
// after
{"multi_tenant_spec":{"tenant_id_column_name":"tenant_id","tenant_id_column_type":"INT64"}} Defensive patterns
Strategy: validation
Validate before calling
spec := targetVSchema.MultiTenantSpec
if spec == nil || spec.TenantIdColumnName == "" {
return errors.New("multi_tenant_spec.tenant_id_column_name must be set")
} Type guard
func tenantColumnDefined(vs *vindexes.KeyspaceSchema) bool {
return vs != nil && vs.MultiTenantSpec != nil && vs.MultiTenantSpec.TenantIdColumnName != ""
} Try / catch
expr, err := getTenantClause(vrOptions, targetVSchema, parser)
if err != nil && strings.Contains(err.Error(), "tenant column name not defined") {
return fmt.Errorf("fix multi_tenant_spec in vschema: %w", err)
} Prevention
- Always set both tenant_id_column_name and tenant_id_column_type together
- Lint vschema files for empty required fields
- Verify the tenant column exists in the source tables too
When it happens
Trigger: Running a VReplication workflow with --tenant-id where the target keyspace vschema has a multi_tenant_spec but omits tenant_id_column_name (or sets it to "").
Common situations: Partially written vschema — spec added but column name field left blank, or a copy/paste from a template where only the column type was set.
Related errors
- target keyspace not defined, or it does not have multi-tenan
- table %v not found in vschema
- table %v not found in vschema
- vindex %s not found in vschema
- table %s not found in vschema for keyspace %s
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/3e8c08edb8794979.
Report an issue: GitHub.