vitessio/vitess · error
a conflicting vindex named %s already exists in the source v
Error message
a conflicting vindex named %s already exists in the source vschema
What it means
During CreateLookupVindex, Vitess validates that the vindex name you are creating does not already exist in the source keyspace's vschema with a different definition. If a vindex with the same name exists but its type/params/owner differ from the one being created (compared via proto.Equal), creation is refused. If it exists with an identical definition, the call proceeds idempotently.
Source
Thrown at go/vt/wrangler/materializer.go:626
}
// If source and target keyspaces are same, Make vschemas point to the same object.
if keyspace == targetKeyspace {
targetVSchema = sourceVSchema
} else {
targetVSchema, err = wr.ts.GetVSchema(ctx, targetKeyspace)
if err != nil {
return nil, nil, nil, err
}
}
if targetVSchema.Vindexes == nil {
targetVSchema.Vindexes = make(map[string]*vschemapb.Vindex)
}
if targetVSchema.Tables == nil {
targetVSchema.Tables = make(map[string]*vschemapb.Table)
}
if existing, ok := sourceVSchema.Vindexes[vindexName]; ok {
if !proto.Equal(existing, vindex) {
return nil, nil, nil, fmt.Errorf("a conflicting vindex named %s already exists in the source vschema", vindexName)
}
}
sourceVSchemaTable = sourceVSchema.Tables[sourceTableName]
if sourceVSchemaTable == nil {
if !schema.IsInternalOperationTableName(sourceTableName) {
return nil, nil, nil, fmt.Errorf("source table %s not found in vschema", sourceTableName)
}
}
for _, colVindex := range sourceVSchemaTable.ColumnVindexes {
// For a conflict, the vindex name and column should match.
if colVindex.Name != vindexName {
continue
}
colName := colVindex.Column
if len(colVindex.Columns) != 0 {
colName = colVindex.Columns[0]
}
if colName == sourceVindexColumns[0] {View on GitHub (pinned to 01a25a7d17)
Solutions
- Check the existing vindex with `vtctldclient GetVSchema <keyspace>` and either use a new, unique vindex name or delete/rename the conflicting one
- If the existing vindex is intentionally identical, re-run with the exact same spec so proto.Equal passes and the call is idempotent
- If the old vindex is no longer wanted, remove it and its ColumnVindex entry from the source vschema, then retry
Example fix
// before (conflicting redefinition)
{"name":"user_lookup","type":"consistent_lookup_unique","owner":"users"} // existing: type lookup, no owner
// after: pick a fresh name or match the existing definition exactly
{"name":"user_lookup_v2","type":"consistent_lookup_unique","owner":"users"} Defensive patterns
Strategy: validation
Validate before calling
vs, _ := ts.GetVSchema(ctx, keyspace)
if existing, ok := vs.Vindexes[vindexName]; ok && !proto.Equal(existing, vindex) {
return fmt.Errorf("vindex %s already exists with a different definition", vindexName)
} Type guard
func hasConflictingVindex(vs *vschemapb.Keyspace, name string, want *vschemapb.Vindex) bool {
existing, ok := vs.Vindexes[name]
return ok && !proto.Equal(existing, want)
} Try / catch
if err := wr.CreateLookupVindex(ctx, ks, vindex, tables, cols, owner, opts); err != nil {
if strings.Contains(err.Error(), "conflicting vindex") {
// reconcile vschema or pick a new vindex name
return reconcileVindex(err)
}
return err
} Prevention
- Fetch the current vschema and diff your vindex definition before creating
- Use descriptive, unique vindex names (e.g. <table>_<purpose>_lookup)
- Treat CreateLookupVindex as idempotent only when the spec matches exactly
When it happens
Trigger: Calling CreateLookupVindex (vtctld `CreateLookupVindex` / `Materialize`) with a vindex whose name already exists in the source keyspace's vschema but was defined with a different type, params (e.g. data_type), or owner.
Common situations: Re-running an earlier CreateLookupVindex after editing the vindex JSON spec; two operators creating vindexes with colliding names; leftover vindex from a partially-completed earlier backfill with tweaked settings.
Related errors
- ColumnVindex for table %v already exists: %v, please remove
- a conflicting vindex named %v already exists in the target v
- a conflicting table named %v already exists in the target vs
- no sharded vschema was provided, so you will need to update
- source table %s not found in vschema
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/603b9e3b3d9c6d07.
Report an issue: GitHub.