vitessio/vitess · error · topo.NewError(topo.NoUpdateNeeded)
%w: uid %v is already in use
Error message
%w: uid %v is already in use
What it means
Returned by AddShardSourceShard (vreplication source registration) when the requested UID already exists among the shard's SourceShards. It is wrapped in a topo.NoUpdateNeeded error so the shard's version is not bumped. Each SourceShard entry needs a unique UID for the filtered replication pipeline.
Source
Thrown at go/vt/vtctl/grpcvtctldserver/server.go:4357
span.Annotate("uid", req.Uid)
span.Annotate("source_keyspace", req.SourceKeyspace)
span.Annotate("source_shard", req.SourceShard)
span.Annotate("keyrange", key.KeyRangeString(req.KeyRange))
span.Annotate("tables", strings.Join(req.Tables, ","))
var si *topo.ShardInfo
ctx, unlock, lockErr := s.ts.LockKeyspace(ctx, req.Keyspace, fmt.Sprintf("SourceShardAdd(%v)", req.Uid))
if lockErr != nil {
err = lockErr
return nil, err
}
defer unlock(&err)
si, err = s.ts.UpdateShardFields(ctx, req.Keyspace, req.Shard, func(si *topo.ShardInfo) error {
for _, ss := range si.SourceShards {
if ss.Uid == req.Uid {
return fmt.Errorf("%w: uid %v is already in use", topo.NewError(topo.NoUpdateNeeded, fmt.Sprintf("%s/%s", req.Keyspace, req.Shard)), req.Uid)
}
}
si.SourceShards = append(si.SourceShards, &topodatapb.Shard_SourceShard{
Keyspace: req.SourceKeyspace,
Shard: req.SourceShard,
Uid: req.Uid,
KeyRange: req.KeyRange,
Tables: req.Tables,
})
return nil
})
if err != nil {
return nil, err
}
resp = &vtctldatapb.SourceShardAddResponse{}
switch si {View on GitHub (pinned to 01a25a7d17)
Solutions
- List existing SourceShards (`vtctldclient GetShard <keyspace/shard>`) and pick a free UID
- Remove the stale SourceShard with RemoveShardSourceShard before re-adding
- Re-use the existing SourceShard if it already has the desired configuration instead of adding a duplicate
Example fix
// before vtctldclient AddShardSourceShard merchant/0 --uid 1 --source merchantcopy/0 # uid 1 already in use // after vtctldclient AddShardSourceShard merchant/0 --uid 2 --source merchantcopy/0 # free uid
Defensive patterns
Strategy: validation
Validate before calling
shard, _ := topoServer.GetShard(ctx, keyspace, shardName)
uids := map[uint32]bool{}
for _, ss := range shard.SourceShards { uids[ss.Uid] = true }
if uids[requestedUID] { /* pick another uid or remove existing first */ } Try / catch
try {
client.addShardSourceShard(keyspace, shard, sourceKeyspace, sourceShard, uid)
} catch (e) {
if (String(e).includes('is already in use')) {
existing = getExistingSourceShard(uid) // reuse or remove first
} else { throw e }
} Prevention
- Track SourceShard UIDs centrally in migration tooling instead of hardcoding
- Read the shard's existing SourceShards before choosing a UID
- Make reshard setup scripts idempotent — check before add
- Use distinct UID ranges per migration to avoid collisions
When it happens
Trigger: Calling `vtctldclient AddShardSourceShard` with a `--uid` value that collides with an existing SourceShard on the target shard.
Common situations: Re-running a reshard/migration setup script without cleaning up previous SourceShards; picking UIDs manually instead of tracking existing ones; resharding workflow partially completed earlier.
Related errors
- %w: no SourceShard with uid %v
- some streams already exist in the target shards, please clea
- shard %v/%v has no primary
- can't get primary tablet record %v: %v
- no vitess cluster found with name %s
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/5280dfeae9653127.
Report an issue: GitHub.