vitessio/vitess · error

GetShard(%v, %v): %w

Error message

GetShard(%v, %v): %w

What it means

CopyShards wraps errors from fromTS.GetShard(ctx, keyspace, shard) with the keyspace and shard names. Shard names were listed successfully but reading the individual Shard record from the source topo failed, aborting the copy before any destination write.

Source

Thrown at go/vt/topo/helpers/copy.go:94

}

// CopyShards will create the shards in the destination topo.
func CopyShards(ctx context.Context, fromTS, toTS *topo.Server) error {
	keyspaces, err := fromTS.GetKeyspaces(ctx)
	if err != nil {
		return fmt.Errorf("fromTS.GetKeyspaces: %w", err)
	}

	for _, keyspace := range keyspaces {
		shards, err := fromTS.GetShardNames(ctx, keyspace)
		if err != nil {
			return fmt.Errorf("GetShardNames(%v): %w", keyspace, err)
		}

		for _, shard := range shards {
			si, err := fromTS.GetShard(ctx, keyspace, shard)
			if err != nil {
				return fmt.Errorf("GetShard(%v, %v): %w", keyspace, shard, err)
			}

			if err := toTS.CreateShard(ctx, keyspace, shard); err != nil {
				if topo.IsErrType(err, topo.NodeExists) {
					log.Warn(fmt.Sprintf("shard %v/%v already exists", keyspace, shard))
				} else {
					return fmt.Errorf("CreateShard(%v, %v): %w", keyspace, shard, err)
				}
			}
			if _, err := toTS.UpdateShardFields(ctx, keyspace, shard, func(toSI *topo.ShardInfo) error {
				toSI.Shard = si.CloneVT()
				return nil
			}); err != nil {
				return fmt.Errorf("UpdateShardFields(%v, %v): %w", keyspace, shard, err)
			}
		}
	}

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Identify the exact keyspace/shard from the message and check its node in the source topo backend directly.
  2. If NoNode, re-run after concurrent shard operations settle, or skip the missing shard.
  3. Retry the copy; destination-side steps are idempotent (NodeExists tolerated).
  4. Repair or remove corrupt shard records in the source topo if unmarshaling fails.

Example fix

// before
si, err := fromTS.GetShard(ctx, keyspace, shard)
if err != nil {
	return fmt.Errorf("GetShard(%v, %v): %w", keyspace, shard, err)
}
// after
si, err := fromTS.GetShard(ctx, keyspace, shard)
if err != nil {
	if topo.IsErrType(err, topo.NoNode) {
		log.Warn(fmt.Sprintf("shard %v/%v gone, skipping", keyspace, shard))
		continue
	}
	return fmt.Errorf("GetShard(%v, %v): %w", keyspace, shard, err)
}
Defensive patterns

Strategy: type-guard

Validate before calling

_, err := fromTS.GetShard(ctx, ks, shard)
if err != nil && topo.IsErrType(err, topo.NoNode) {
	// shard record missing; skip or repair
}

Type guard

func shardMissing(err error) bool {
	return topo.IsErrType(err, topo.NoNode)
}

Try / catch

si, err := fromTS.GetShard(ctx, keyspace, shard)
if err != nil {
	if topo.IsErrType(err, topo.NoNode) {
		continue
	}
	return fmt.Errorf("GetShard(%v, %v): %w", keyspace, shard, err)
}

Prevention

When it happens

Trigger: Calling CopyShards when GetShard returns a connection error, NoNode (shard removed concurrently), or unmarshal failure on a corrupt shard record.

Common situations: Concurrent shard teardown/pruning while copying; etcd/zk instability mid-scan; partially deleted shard directories left by earlier failed operations.

Related errors


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