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

  1. Set tenant_id_column_name in the target keyspace's multi_tenant_spec and re-apply the vschema
  2. Confirm the tenant column actually exists in the replicated tables
  3. 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

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


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