vitessio/vitess · error

ReadTopologyInstance will not act on empty tablet alias

Error message

ReadTopologyInstance will not act on empty tablet alias

What it means

ReadTopologyInstanceBufferable validates its input before doing any work and refuses to proceed when the tabletAlias pointer is nil. This is a defensive guard because a nil alias cannot identify a tablet to discover. Callers must always pass a valid *topodatapb.TabletAlias.

Source

Thrown at go/vt/vtorc/inst/instance_dao.go:181

// - timing information can be collected for the stages performed.
func ReadTopologyInstanceBufferable(tabletAlias *topodatapb.TabletAlias, latency *stopwatch.NamedStopwatch) (inst *Instance, err error) {
	defer func() {
		if r := recover(); r != nil {
			err = logReadTopologyInstanceError(tabletAlias, "Unexpected, aborting", tb.Errorf("%+v", r))
		}
	}()

	var tablet *topodatapb.Tablet
	var fs *replicationdatapb.FullStatus
	readingStartTime := time.Now()
	stalledDisk := false
	instance := NewInstance()
	instanceFound := false
	partialSuccess := false
	errorChan := make(chan error, 32)

	if tabletAlias == nil {
		return instance, errors.New("ReadTopologyInstance will not act on empty tablet alias")
	}

	lastAttemptedCheckTimer := time.AfterFunc(time.Second, func() {
		go func() {
			_ = UpdateInstanceLastAttemptedCheck(tabletAlias)
		}()
	})

	latency.Start("instance")

	tablet, err = ReadTablet(tabletAlias)
	if err != nil {
		goto Cleanup
	}
	if tablet == nil {
		// This can happen because Orc rediscovers instances by alt hostnames,
		// lit localhost, ip, etc.
		// TODO(sougou): disable this ability.

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Check the caller that produced the nil alias and fix the upstream lookup so it either returns a valid alias or an error.
  2. Guard the call site: skip or log when the alias is nil before invoking discovery.
  3. Run vtorc with debug logging to find which tablet source produced the nil alias.

Example fix

// before
inst, err := inst.ReadTopologyInstanceBufferable(ctx, nil, hint)
// after
if alias == nil {
    return errors.New("cannot discover: tablet alias is nil")
}
inst, err := inst.ReadTopologyInstanceBufferable(ctx, alias, hint)
Defensive patterns

Strategy: validation

Validate before calling

if tabletAlias == nil {
    return errors.New("cannot discover: tablet alias is nil")
}

Type guard

func validAlias(a *topodatapb.TabletAlias) bool {
    return a != nil && a.Uid != 0 && a.Cell != ""
}

Try / catch

inst, err := inst.ReadTopologyInstanceBufferable(ctx, alias, hint)
if err != nil && strings.Contains(err.Error(), "empty tablet alias") {
    log.Warn("skipped discovery: nil alias from upstream lookup")
    return nil
} else if err != nil { return err }

Prevention

When it happens

Trigger: Calling ReadTopologyInstanceBufferable (directly or via DiscoverInstance) with tabletAlias == nil, typically when an upstream lookup (e.g., topo server read) returned nil without an error being propagated.

Common situations: A discovery loop iterates over results from a partially failed topo read that yields nil aliases; a bug in code constructing a TabletAlias; reading a tablet from a keyspace/shard where the primary record is empty.

Related errors


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