vitessio/vitess · error

GetTablet(%v): %w

Error message

GetTablet(%v): %w

What it means

CopyTablets wraps errors from fromTS.GetTablet(ctx, tabletAlias) with the tablet alias. Aliases for the cell were listed but reading an individual Tablet record failed, aborting the copy. This happens before the destination CreateTablet/UpdateTablet steps, so the destination is untouched for that tablet.

Source

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

}

// 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
					})
				}
				if err != nil {
					return fmt.Errorf("CreateTablet(%v): %w", tabletAlias, err)
				}
			}
		}
	}

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. If the wrapped cause is topo.NoNode, the tablet vanished concurrently — re-run the copy; it will pick up remaining tablets.
  2. Verify the cell's local topo backend is healthy and reachable.
  3. Check for corrupt tablet records at the alias path and remove/repair them in the topo backend.
  4. Retry the copy; destination tablet creation tolerates NodeExists by updating instead.

Example fix

// before
ti, err := fromTS.GetTablet(ctx, tabletAlias)
if err != nil {
	return fmt.Errorf("GetTablet(%v): %w", tabletAlias, err)
}
// after
ti, err := fromTS.GetTablet(ctx, tabletAlias)
if err != nil {
	if topo.IsErrType(err, topo.NoNode) {
		log.Warn(fmt.Sprintf("tablet %v disappeared, skipping", topoproto.TabletAliasString(tabletAlias)))
		continue
	}
	return fmt.Errorf("GetTablet(%v): %w", tabletAlias, err)
}
Defensive patterns

Strategy: type-guard

Validate before calling

aliases, _ := fromTS.GetTabletAliasesByCell(ctx, cell)
for _, a := range aliases {
	if _, err := fromTS.GetTablet(ctx, a); topo.IsErrType(err, topo.NoNode) {
		// stale alias; skip it in the copy run
	}
}

Type guard

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

Try / catch

ti, err := fromTS.GetTablet(ctx, tabletAlias)
if err != nil {
	if topo.IsErrType(err, topo.NoNode) {
		continue
	}
	return fmt.Errorf("GetTablet(%v): %w", tabletAlias, err)
}

Prevention

When it happens

Trigger: Calling CopyTablets when GetTablet returns NoNode (tablet deleted between listing aliases and fetching the record — common race), a per-cell topo connection failure, or unmarshal failure on a corrupt tablet record.

Common situations: Tablets being killed/reparented concurrently while the copy runs (vttablet shutdown, tabletmanager operations); stale tablet entries left after a cell was wiped; per-cell etcd unavailability mid-scan.

Related errors


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