vitessio/vitess · error

table %v not found in vschema

Error message

table %v not found in vschema

What it means

templatizeRule looks up each filter rule's Match table in the source keyspace's vschema (SourceKeyspaceSchema). If the table is absent from the vschema and is not a Vitess internal operation table (_vt_HEX..., etc.), the rule cannot be classified as sharded or reference, so this error is thrown. It means the vreplication filter references a table Vitess does not know about.

Source

Thrown at go/vt/vtctl/workflow/stream_migrator.go:1115

				}
				streamType = StreamTypeReference
			}
		}

		if streamType == StreamTypeSharded {
			shardedStreams = append(shardedStreams, vrs)
		}
	}

	return shardedStreams, nil
}

// templatizeRule replaces keyrange values with {{.}}.
// This can then be used by go's template package to substitute other keyrange values.
func (sm *StreamMigrator) templatizeRule(ctx context.Context, rule *binlogdatapb.Rule) (StreamType, error) {
	vtable, ok := sm.ts.SourceKeyspaceSchema().Tables[rule.Match]
	if !ok && !schema.IsInternalOperationTableName(rule.Match) {
		return StreamTypeUnknown, fmt.Errorf("table %v not found in vschema", rule.Match)
	}

	if vtable != nil && vtable.Type == vindexes.TypeReference {
		return StreamTypeReference, nil
	}

	switch {
	case rule.Filter == "":
		return StreamTypeUnknown, fmt.Errorf("rule %v does not have a select expression in vreplication", rule)
	case key.IsValidKeyRange(rule.Filter):
		rule.Filter = "{{.}}"
		return StreamTypeSharded, nil
	case rule.Filter == vreplication.ExcludeStr:
		return StreamTypeUnknown, fmt.Errorf("unexpected rule in vreplication: %v", rule)
	default:
		if err := sm.templatizeKeyRange(ctx, rule); err != nil {
			return StreamTypeUnknown, err
		}

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Compare the rule's Match against the keyspace vschema (`show vschema tables` / check the vschema json) and fix or remove the stale rule.
  2. Cancel and recreate the vreplication workflow with a filter covering only tables that exist in the source vschema.
  3. If the table should exist, re-run ReloadSchema on the source tablets and ensure the vschema defines the table with vindexes.
  4. Check whether the table is a newer internal operation table and upgrade Vitess if the version predates its recognition (schema.IsInternalOperationTableName).

Example fix

// before: rule.Match='staging.orders' but orders not in vschema
// after: add to vschema or drop the rule
// vschema: "orders": {"type": "scalar"}  (or recreate workflow without that rule)
Defensive patterns

Strategy: validation

Validate before calling

-- Every rule.Match must exist in the source keyspace vschema
-- SHOW VSCHEMA TABLES; compare against:
SELECT id, workflow, source FROM _vt.vreplication;  -- parse rules and check Match names

Type guard

func tableInVschema(table string, vs *vschema.VSchema) bool { _, ok := vs.Tables[table]; return ok }

Prevention

When it happens

Trigger: templatize -> templatizeRule during BuildStreamMigrator/StopStreams where rule.Match names a table missing from sm.ts.SourceKeyspaceSchema().Tables — e.g. the table was dropped, the vschema doesn't declare it, or the keyspace's schema view is stale.

Common situations: Table dropped after the workflow was created; table exists only in MySQL but has no vindex/vschema definition; keyspace was resharded/renamed and the source schema cache is stale; typo in the rule Match used when the workflow was built; internal tables that the running Vitess version doesn't recognize.

Related errors


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