vitessio/vitess · error

no primary in shard record %v/%v. Consider running 'vtctl In

Error message

no primary in shard record %v/%v. Consider running 'vtctl InitShardPrimary' in case of a new shard or reparenting the shard to fix the topology data

What it means

CopySchemaShard requires the destination shard to have a PrimaryAlias, because the schema is applied directly on the destination primary and propagates to replicas via binlogs. This error is returned when the destination shard record exists but PrimaryAlias == nil — no primary is currently assigned. The message recommends InitShardPrimary or reparenting.

Source

Thrown at go/vt/wrangler/schema.go:210

	if sourceShardInfo.PrimaryAlias == nil {
		return fmt.Errorf("no primary in shard record %v/%v. Consider running 'vtctl InitShardPrimary' in case of a new shard or reparenting the shard to fix the topology data, or providing a non-primary tablet alias", sourceKeyspace, sourceShard)
	}

	return wr.CopySchemaShard(ctx, sourceShardInfo.PrimaryAlias, tables, excludeTables, includeViews, destKeyspace, destShard, waitReplicasTimeout, skipVerify)
}

// CopySchemaShard copies the schema from a source tablet to the
// specified shard.  The schema is applied directly on the primary of
// the destination shard, and is propagated to the replicas through
// binlogs.
func (wr *Wrangler) CopySchemaShard(ctx context.Context, sourceTabletAlias *topodatapb.TabletAlias, tables, excludeTables []string, includeViews bool, destKeyspace, destShard string, waitReplicasTimeout time.Duration, skipVerify bool) error {
	destShardInfo, err := wr.ts.GetShard(ctx, destKeyspace, destShard)
	if err != nil {
		return fmt.Errorf("GetShard(%v, %v) failed: %v", destKeyspace, destShard, err)
	}

	if destShardInfo.PrimaryAlias == nil {
		return fmt.Errorf("no primary in shard record %v/%v. Consider running 'vtctl InitShardPrimary' in case of a new shard or reparenting the shard to fix the topology data", destKeyspace, destShard)
	}

	diffs, err := schematools.CompareSchemas(ctx, wr.ts, wr.tmc, sourceTabletAlias, destShardInfo.PrimaryAlias, tables, excludeTables, includeViews)
	if err != nil {
		return fmt.Errorf("CopySchemaShard failed because schemas could not be compared initially: %v", err)
	}
	if diffs == nil {
		// Return early because dest has already the same schema as source.
		return nil
	}

	req := &tabletmanagerdatapb.GetSchemaRequest{Tables: tables, ExcludeTables: excludeTables, IncludeViews: includeViews}
	sourceSd, err := schematools.GetSchema(ctx, wr.ts, wr.tmc, sourceTabletAlias, req)
	if err != nil {
		return fmt.Errorf("GetSchema(%v, %v, %v, %v) failed: %v", sourceTabletAlias, tables, excludeTables, includeViews, err)
	}

	createSQLstmts := tmutils.SchemaDefinitionToSQLStrings(sourceSd)

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Run vtctl InitShardPrimary <destKeyspace>/<destShard> <tablet-alias> to assign a primary.
  2. Or perform PlannedReparentShard to restore the primary.
  3. Verify with vtctl GetShard that PrimaryAlias is populated before retrying CopySchemaShard.
  4. If a primary is not desired, copy schema to a specific tablet using alternative tooling.

Example fix

// before (dest has no primary)
wr.CopySchemaShard(ctx, srcAlias, nil, nil, true, "ks", "-80", timeout, false)
// after
vtctl InitShardPrimary ks/-80 cell1-0000000200
wr.CopySchemaShard(ctx, srcAlias, nil, nil, true, "ks", "-80", timeout, false)
Defensive patterns

Strategy: validation

Validate before calling

si, err := ts.GetShard(ctx, destKeyspace, destShard)
if err != nil { return err }
if si.PrimaryAlias == nil {
	return fmt.Errorf("dest shard %s/%s has no primary; run InitShardPrimary first", destKeyspace, destShard)
}

Type guard

func hasPrimary(si *topo.ShardInfo) bool { return si != nil && si.PrimaryAlias != nil }

Try / catch

err := wr.CopySchemaShard(...)
if err != nil && strings.Contains(err.Error(), "no primary in shard record") {
	// run InitShardPrimary / PlannedReparentShard then retry
}

Prevention

When it happens

Trigger: Calling CopySchemaShard against a destination shard whose topology record has no primary: brand-new shard never primaried, primary lost after failure and not re-elected, or stale topo data after reparenting.

Common situations: Setting up a new shard intended as a schema-copy target but skipping InitShardPrimary; shard in emergency failover state; topo record corrupted after a manual reparent attempt.

Related errors


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