vitessio/vitess · error

failed to get shard %s/%s: %v

Error message

failed to get shard %s/%s: %v

What it means

CloneFromDonor wraps a topo.GetShard failure when resolving the primary of the target shard for a CLONE-based restore. The shard record could not be read from the topology server, so the donor tablet alias cannot be determined.

Source

Thrown at go/vt/mysqlctl/clone.go:86

	utils.SetFlagBoolVar(fs, &cloneFromPrimary, "clone-from-primary", cloneFromPrimary, "Clone data from the primary tablet in the shard using MySQL CLONE REMOTE instead of restoring from backup. Requires MySQL 8.0.17+. Mutually exclusive with --clone-from-tablet.")
	utils.SetFlagStringVar(fs, &cloneFromTablet, "clone-from-tablet", cloneFromTablet, "Clone data from this tablet using MySQL CLONE REMOTE instead of restoring from backup (tablet alias, e.g., zone1-123). Requires MySQL 8.0.17+. Mutually exclusive with --clone-from-primary.")
	utils.SetFlagDurationVar(fs, &cloneRestartWaitTimeout, "clone-restart-wait-timeout", cloneRestartWaitTimeout, "Timeout for waiting for MySQL to restart after CLONE REMOTE.")
}

// 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.

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Verify keyspace/shard names with `vtctldclient GetShard <keyspace>/<shard>`.
  2. Check topology server connectivity and flags (topo implementation, server address).
  3. Create the shard if it doesn't exist (`vtctldclient CreateKeyspace`/`CreateShard`).
  4. Retry after topo server recovers if it was a transient outage.
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-check
if _, err := vtctldclientExecute("GetShard", keyspace+"/"+shard); err != nil {
	// abort before starting restore
}

Try / catch

pos, err := mysqlctl.CloneFromDonor(ctx, ...)
if err != nil && strings.Contains(err.Error(), "failed to get shard") {
	// check topo connectivity / shard existence before retry
}

Prevention

When it happens

Trigger: Calling CloneFromDonor (or restoreFromCloneLocked) with --clone-from-primary where the topology connection fails, the shard does not exist, or the topo backend is unreachable.

Common situations: Typo in keyspace/shard name, vtctld/topo (etcd/zk) outage, shard never created, running against the wrong topo server (wrong flags/env).

Related errors


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