vitessio/vitess · error
target keyspace not defined, or it does not have multi-tenan
Error message
target keyspace not defined, or it does not have multi-tenant spec
What it means
getTenantClause builds a tenant-filtering SQL expression for VReplication queries when VReplicationOptions.TenantId is set. It requires the target keyspace's vschema to define a MultiTenantSpec. If the target keyspace has no vschema or lacks that spec, the tenant clause cannot be built and this error is returned.
Source
Thrown at go/vt/vtctl/workflow/utils.go:845
Right: sel.Where.Expr,
},
}
} else {
sel.Where = &sqlparser.Where{
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:View on GitHub (pinned to 01a25a7d17)
Solutions
- Add a multi_tenant_spec (with tenant_id_column_name and tenant_id_column_type) to the target keyspace's vschema and apply it (vtctldclient ApplyVSchema)
- Verify the target keyspace name in the workflow matches the vschema entry exactly
- Drop the --tenant-id flag if tenant filtering is not actually intended
Example fix
// before (vschema)
{"keyspaces":{"commerce":{}}}
// after
{"keyspaces":{"commerce":{"multi_tenant_spec":{"tenant_id_column_name":"tenant_id","tenant_id_column_type":"INT64"}}}} Defensive patterns
Strategy: validation
Validate before calling
ksVs, err := ts.TopoServer().GetVSchema(ctx, targetKeyspace)
if err != nil || ksVs == nil || ksVs.MultiTenantSpec == nil {
return errors.New("target keyspace vschema must define multi_tenant_spec before using --tenant-id")
} Type guard
func hasMultiTenantSpec(vs *vschemapb.Keyspace) bool {
return vs != nil && vs.MultiTenantSpec != nil
} Try / catch
expr, err := getTenantClause(vrOptions, targetVSchema, parser)
if err != nil && errors.Is(err, errors.New("target keyspace not defined, or it does not have multi-tenant spec")) {
return fmt.Errorf("apply multi_tenant_spec to %s vschema first: %w", targetKeyspace, err)
} Prevention
- Apply the multi-tenant vschema before starting tenant-scoped MoveTables
- Validate the vschema JSON against the multi_tenant_spec schema
- Double-check keyspace name spelling matches the vschema entry
When it happens
Trigger: Running a VReplication operation with --tenant-id (vrOptions.TenantId non-empty) against a target keyspace whose vschema lacks `multi_tenant_spec` in its keyspace section, or when targetVSchema is nil (keyspace not found in vschema).
Common situations: Forgetting to add multi_tenant_spec to the target keyspace vschema before running a tenant-filtered MoveTables, misspelling the keyspace name so the vschema lookup returns nil, or using a workflow type that does not support tenant scoping.
Related errors
- tenant column name not defined in multi-tenant spec
- 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/2b3abc5cd2287df0.
Report an issue: GitHub.