vitessio/vitess · error
shard %s/%s has no primary
Error message
shard %s/%s has no primary
What it means
Returned by mysqlctl clone logic when the specified shard in the given keyspace has no primary tablet assigned, so there is no source to clone from.
Source
Thrown at go/vt/mysqlctl/clone.go:89
}
// CloneFromDonor clones data from the specified donor tablet using MySQL CLONE REMOTE and returns the GTID position of the cloned data. If mycnf is non-nil, CloneFromDonor may use it to restart mysqld locally when CLONE completes but MySQL cannot restart itself.
func CloneFromDonor(ctx context.Context, topoServer *topo.Server, mysqld MysqlDaemon, mycnf *Mycnf, keyspace, shard string) (replication.Position, error) {
var donorAlias *topodatapb.TabletAlias
var err error
switch {
case cloneFromPrimary && cloneFromTablet != "":
return replication.Position{}, errors.New("--clone-from-primary and --clone-from-tablet are mutually exclusive")
case cloneFromPrimary:
// Look up the primary tablet from topology.
log.Info(fmt.Sprintf("Looking up primary tablet for shard %s/%s for use as CLONE REMOTE donor", keyspace, shard))
si, err := topoServer.GetShard(ctx, keyspace, shard)
if err != nil {
return replication.Position{}, fmt.Errorf("failed to get shard %s/%s: %v", keyspace, shard, err)
}
if topoproto.TabletAliasIsZero(si.PrimaryAlias) {
return replication.Position{}, fmt.Errorf("shard %s/%s has no primary", keyspace, shard)
}
donorAlias = si.PrimaryAlias
log.Info(fmt.Sprintf("Found primary tablet %s for use as CLONE REMOTE donor", topoproto.TabletAliasString(donorAlias)))
case cloneFromTablet != "":
// Parse the explicit donor tablet alias.
log.Info(fmt.Sprintf("Using tablet %s for use as CLONE REMOTE donor", cloneFromTablet))
donorAlias, err = topoproto.ParseTabletAlias(cloneFromTablet)
if err != nil {
return replication.Position{}, fmt.Errorf("invalid tablet alias %q: %v", cloneFromTablet, err)
}
default:
return replication.Position{}, errors.New("no donor specified")
}
// Get donor tablet info from topology.
donorTablet, err := topoServer.GetTablet(ctx, donorAlias)
if err != nil {
return replication.Position{}, fmt.Errorf("failed to get tablet %s from topology: %v", topoproto.TabletAliasString(donorAlias), err)View on GitHub (pinned to 01a25a7d17)
Solutions
- Check the shard with `vtctldclient GetShard <keyspace>/<shard>` — wait for or trigger primary election (PlannedReparentShard / EmergencyReparentShard).
- Choose a specific donor with --clone-from-tablet instead of --clone-from-primary.
- Ensure a tablet is started and promoted to primary for that shard.
- Verify you are targeting the correct keyspace/shard.
Example fix
// before vttablet --clone-from-primary ... // after vttablet --clone-from-tablet zone1-0000000100 ...
Defensive patterns
Strategy: validation
Validate before calling
shardInfo, _ := topoServer.GetShard(ctx, keyspace, shard)
if shardInfo == nil || shardInfo.PrimaryAlias == nil || shardInfo.PrimaryAlias.Uid == 0 {
return errors.New("shard has no primary; use --clone-from-tablet instead")
} Try / catch
if err != nil && strings.Contains(err.Error(), "has no primary") {
// fall back to --clone-from-tablet with a known replica
} Prevention
- Ensure a primary is elected before restores
- Use --clone-from-tablet when primary availability is uncertain
When it happens
Trigger: CloneFromDonor with --clone-from-primary on a shard with no primary (e.g., during resharding setup, after primary failure before failover, or a fresh shard with no tablets).
Common situations: Mid-failout/failover window, orphan shard, Principaled shard not yet elected, user targeting wrong shard that is intentionally empty.
Related errors
- no primary tablet found
- failed to get shard %s/%s: %v
- cannot lookup primary tablet %v for shard %v/%v: %w
- shard not found
- failed to get tablet %s from topology: %v
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/8f3aa5c92322daef.
Report an issue: GitHub.