vitessio/vitess · error

a conflicting table named %v already exists in the target vs

Error message

a conflicting table named %v already exists in the target vschema

What it means

CreateLookupVindex builds a target-vschemapb.Table describing the new lookup table's ColumnVindexes and checks the target vschema's Tables map. If the target table name already exists there with a different configuration (proto.Equal fails), creation is refused to avoid silently overwriting the existing table's vindex setup.

Source

Thrown at go/vt/wrangler/materializer.go:773

			if !proto.Equal(existing, targetVindex) {
				return nil, nil, nil, fmt.Errorf("a conflicting vindex named %v already exists in the target vschema", targetVindexType)
			}
		} else {
			targetVSchema.Vindexes[targetVindexType] = targetVindex
		}

		targetTable = &vschemapb.Table{
			ColumnVindexes: []*vschemapb.ColumnVindex{{
				Column: vindexFromCols[0],
				Name:   targetVindexType,
			}},
		}
	} else {
		targetTable = &vschemapb.Table{}
	}
	if existing, ok := targetVSchema.Tables[targetTableName]; ok {
		if !proto.Equal(existing, targetTable) {
			return nil, nil, nil, fmt.Errorf("a conflicting table named %v already exists in the target vschema", targetTableName)
		}
	} else {
		targetVSchema.Tables[targetTableName] = targetTable
	}

	ms = &vtctldatapb.MaterializeSettings{
		Workflow:              targetTableName + "_vdx",
		MaterializationIntent: vtctldatapb.MaterializationIntent_CREATELOOKUPINDEX,
		SourceKeyspace:        keyspace,
		TargetKeyspace:        targetKeyspace,
		StopAfterCopy:         vindex.Owner != "" && !continueAfterCopyWithOwner,
		TableSettings: []*vtctldatapb.TableMaterializeSettings{{
			TargetTable:      targetTableName,
			SourceExpression: materializeQuery,
			CreateDdl:        createDDL,
		}},
	}

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Pick a different target lookup table name, or remove/reconcile the existing entry in the target vschema and retry
  2. Compare the existing vschema table config (`vtctldclient GetVSchema <target-keyspace>`) with what CreateLookupVindex would create and align them
  3. If a previous attempt left the entry, clean up the leftover lookup table and vschema entry before re-running

Example fix

// before: stale target table entry differs
"customer_lookup": {"column_vindexes": [{"name":"hash","column":"cust_id"}]}
// after: remove it or choose a new lookup table name
"customer_lookup_v2": {}
Defensive patterns

Strategy: validation

Validate before calling

tvs, _ := ts.GetVSchema(ctx, targetKeyspace)
if tvs.Tables[targetTableName] != nil {
    return fmt.Errorf("target table %s already configured in vschema; reconcile first", targetTableName)
}

Type guard

func targetTableConfigured(tvs *vschemapb.Keyspace, table string) bool {
    return tvs.Tables != nil && tvs.Tables[table] != nil
}

Try / catch

if err := createLookupVindex(...); err != nil {
    if strings.Contains(err.Error(), "conflicting table named") {
        return reconcileTargetTable(targetKS, targetTable) // align or remove entry, retry
    }
    return err
}

Prevention

When it happens

Trigger: The chosen target (lookup) table name already exists in the target keyspace vschema with different ColumnVindexes than the ones Vitess would generate — e.g. a previous CreateLookupVindex or a manually configured table entry.

Common situations: Re-running CreateLookupVindex after changing the target table's config; reusing an existing lookup table name from another vindex; stale vschema from an aborted earlier attempt.

Related errors


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