vitessio/vitess · error

GetTabletsByCell(%v): %w

Error message

GetTabletsByCell(%v): %w

What it means

CopyTablets wraps errors from fromTS.GetTabletAliasesByCell(ctx, cell) with the failing cell name (the message text uses the older GetTabletsByCell name). Cells were listed but enumerating tablet aliases within one cell failed, aborting the copy before any destination write for that cell.

Source

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

				return fmt.Errorf("UpdateShardFields(%v, %v): %w", keyspace, shard, err)
			}
		}
	}

	return nil
}

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

	for _, cell := range cells {
		tabletAliases, err := fromTS.GetTabletAliasesByCell(ctx, cell)
		if err != nil {
			return fmt.Errorf("GetTabletsByCell(%v): %w", cell, err)
		} else {
			for _, tabletAlias := range tabletAliases {
				// read the source tablet
				ti, err := fromTS.GetTablet(ctx, tabletAlias)
				if err != nil {
					return fmt.Errorf("GetTablet(%v): %w", tabletAlias, err)
				}

				// try to create the destination
				err = toTS.CreateTablet(ctx, ti.Tablet)
				if topo.IsErrType(err, topo.NodeExists) {
					// update the destination tablet
					log.Warn(fmt.Sprintf("tablet %v already exists, updating it", tabletAlias))
					_, err = toTS.UpdateTabletFields(ctx, tabletAlias, func(t *topodatapb.Tablet) error {
						proto.Merge(t, ti.Tablet)
						return nil
					})
				}

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Check that the named cell exists and its local topo backend is reachable (each cell may have its own topo instance).
  2. If the cell was decommissioned, prune the stale cell entry from the source topo and retry.
  3. If NoNode for the cell's tablets path, remove leftovers or skip the cell.
  4. Retry the copy after the cell's topo instance recovers.

Example fix

// before
tabletAliases, err := fromTS.GetTabletAliasesByCell(ctx, cell)
if err != nil {
	return fmt.Errorf("GetTabletsByCell(%v): %w", cell, err)
} else {
	for _, tabletAlias := range tabletAliases {
// after
tabletAliases, err := fromTS.GetTabletAliasesByCell(ctx, cell)
if err != nil {
	if topo.IsErrType(err, topo.NoNode) {
		log.Warn(fmt.Sprintf("cell %v has no tablets, skipping", cell))
		continue
	}
	return fmt.Errorf("GetTabletsByCell(%v): %w", cell, err)
}
for _, tabletAlias := range tabletAliases {
Defensive patterns

Strategy: type-guard

Validate before calling

cells, _ := fromTS.GetKnownCells(ctx)
for _, c := range cells {
	if _, err := fromTS.GetTabletAliasesByCell(ctx, c); err != nil {
		// stale or unreachable cell; prune or fix before copying
	}
}

Type guard

func cellUnavailable(err error) bool {
	return topo.IsErrType(err, topo.NoNode) || topo.IsErrType(err, topo.Unavailable)
}

Try / catch

tabletAliases, err := fromTS.GetTabletAliasesByCell(ctx, cell)
if err != nil {
	if topo.IsErrType(err, topo.NoNode) {
		continue
	}
	return fmt.Errorf("GetTabletsByCell(%v): %w", cell, err)
}

Prevention

When it happens

Trigger: Calling CopyTablets when GetTabletAliasesByCell returns an error: cell missing from the topo (stale cell, NoNode), source topo connection failure, or permission denied on the cell's tablets path.

Common situations: A cell was decommissioned but its entry remains; tablet node directories deleted out from under the tool; per-cell topo (local etcd per cell) down while the global topo is up.

Related errors


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