vitessio/vitess · error

no vschema definition for table %v

Error message

no vschema definition for table %v

What it means

Returned by the binlog keyspace ID resolver when a row's table has no entry in the vschema, so no keyspace ID mapping can be derived for the row.

Source

Thrown at go/vt/binlog/keyspace_id_resolver.go:73

// gets the keyspace part, and uses it to find the column name.
func newKeyspaceIDResolverFactoryV3(ctx context.Context, ts *topo.Server, keyspace string, cell string, parser *sqlparser.Parser) (keyspaceIDResolverFactory, error) {
	srvVSchema, err := ts.GetSrvVSchema(ctx, cell)
	if err != nil {
		return nil, err
	}
	kschema, ok := srvVSchema.Keyspaces[keyspace]
	if !ok {
		return nil, fmt.Errorf("SrvVSchema has no entry for keyspace %v", keyspace)
	}
	keyspaceSchema, err := vindexes.BuildKeyspaceSchema(kschema, keyspace, parser)
	if err != nil {
		return nil, fmt.Errorf("cannot build vschema for keyspace %v: %v", keyspace, err)
	}
	return func(table *schema.Table) (int, keyspaceIDResolver, error) {
		// Find the v3 schema.
		tableSchema, ok := keyspaceSchema.Tables[table.Name.String()]
		if !ok {
			return -1, nil, fmt.Errorf("no vschema definition for table %v", table.Name)
		}

		// use the lowest cost unique vindex as the sharding key
		colVindex, err := vindexes.FindVindexForSharding(table.Name.String(), tableSchema.ColumnVindexes)
		if err != nil {
			return -1, nil, err
		}

		// TODO @rafael - when rewriting the mapping function, this will need to change.
		// for now it's safe to assume the sharding key will be always on index 0.
		shardingColumnName := colVindex.Columns[0].String()
		for i, col := range table.Fields {
			if strings.EqualFold(col.Name, shardingColumnName) {
				// We found the column.
				return i, &keyspaceIDResolverFactoryV3{
					// Only SingleColumn vindexes are returned by FindVindexForSharding.
					vindex: colVindex.Vindex.(vindexes.SingleColumn),
				}, nil

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Add the table (with its column vindexes) to the keyspace vschema via vtctldclient ApplyVSchema.
  2. Rebuild the SrvVSchema and restart the streamer.
  3. Exclude undeclared tables from the filter rules if they should not be streamed.

Example fix

// before
{"tables":{}}
// after
{"tables":{"t1":{"column_vindexes":[{"column":"id","name":"h"}]}}}
Defensive patterns

Strategy: validation

Validate before calling

srv, _ := ts.GetSrvVSchema(ctx, cell)
ks := srv.Keyspaces[keyspace]
for _, tbl := range tablesToStream {
	if _, ok := ks.Tables[tbl]; !ok {
		return fmt.Errorf("table %s missing from vschema for %s", tbl, keyspace)
	}
}

Try / catch

if err := streamKeyRange(ctx, kr); err != nil {
	if strings.Contains(err.Error(), "no vschema definition for table") {
		// add table to vschema, then ApplyVSchema + RebuildKeyspaceGraph
	}
	return err
}

Prevention

When it happens

Trigger: Streaming a keyrange where a DML targets a table absent from keyspaceSchema.Tables (table missing from vschema's table definitions).

Common situations: Table added to MySQL but vschema never updated; unsharded-style schema used in a sharded keyspace; system/temp tables not declared in vschema.

Related errors


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