vitessio/vitess · error

cannot lookup primary tablet %v for shard %v/%v: %w

Error message

cannot lookup primary tablet %v for shard %v/%v: %w

What it means

After finding the shard record, ChangeTabletType fetches the shard's primary tablet record from the topology to validate state. This error wraps the underlying topo error when the primary alias listed in the shard record cannot be fetched, meaning the shard record points at a primary that is missing or unreachable in the topology.

Source

Thrown at go/vt/vtctl/grpcvtctldserver/server.go:702

	durabilityName, err := s.ts.GetKeyspaceDurability(ctx, tablet.Keyspace)
	if err != nil {
		return nil, err
	}
	log.Info(fmt.Sprintf("Getting a new durability policy for %v", durabilityName))
	durability, err := policy.GetDurabilityPolicy(durabilityName)
	if err != nil {
		return nil, err
	}

	if !shard.HasPrimary() {
		err = vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "no primary tablet for shard %v/%v", tablet.Keyspace, tablet.Shard)
		return nil, err
	}

	shardPrimary, err := s.ts.GetTablet(ctx, shard.PrimaryAlias)
	if err != nil {
		err = fmt.Errorf("cannot lookup primary tablet %v for shard %v/%v: %w", topoproto.TabletAliasString(shard.PrimaryAlias), tablet.Keyspace, tablet.Shard, err)
		return nil, err
	}

	if shardPrimary.Type != topodatapb.TabletType_PRIMARY {
		err = vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "TopologyServer has incosistent state for shard primary %v", topoproto.TabletAliasString(shard.PrimaryAlias))
		return nil, err
	}

	if shardPrimary.Keyspace != tablet.Keyspace || shardPrimary.Shard != tablet.Shard {
		err = vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "primary %v and potential replica %v not in same keypace shard (%v/%v)", topoproto.TabletAliasString(shard.PrimaryAlias), req.TabletAlias, tablet.Keyspace, tablet.Shard)
		return nil, err
	}

	// We should clone the tablet and change its type to the expected type before checking the durability rules
	// Since we want to check the durability rules for the desired state and not before we make that change
	expectedTablet := tablet.CloneVT()
	expectedTablet.Type = req.DbType
	err = s.tmc.ChangeType(ctx, tablet.Tablet, req.DbType, policy.IsReplicaSemiSync(durability, shardPrimary.Tablet, expectedTablet))

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Inspect the shard record (vtctldclient GetShard) and verify the primary alias exists via GetTablet
  2. If the primary record is gone, repair the shard record (RemoveShardPrimary or run a reparent) before retrying
  3. Verify topo server connectivity (etcd/zk flags and health) for the vtctld process
  4. Fix the underlying wrapped error reported in the %w cause first
Defensive patterns

Strategy: retry

Validate before calling

shard, err := ts.GetShard(ctx, keyspace, shardName)
if shard.PrimaryAlias != nil {
    if _, err := ts.GetTablet(ctx, shard.PrimaryAlias); err != nil {
        return fmt.Errorf("shard primary record missing, repair topology first")
    }
}

Try / catch

_, err := client.ChangeTabletType(ctx, alias, tt)
if err != nil && strings.Contains(err.Error(), "cannot lookup primary tablet") {
    // inspect GetShard primary alias; run reparent if stale
}

Prevention

When it happens

Trigger: Calling ChangeTabletType on a tablet in a shard whose shard record's PrimaryAlias references a tablet that no longer exists in the topo server (deleted tablet record) or the topo read fails (etcd/ZK connectivity issue).

Common situations: Stale topology after a crashed reparent; manual deletion of tablet records; etcd/ZooKeeper connectivity problems; shard record left pointing at a decommissioned tablet.

Related errors


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