vitessio/vitess · error · ErrTabletAliasNil
tablet alias is nil
Error message
tablet alias is nil
What it means
ErrTabletAliasNil is the sentinel error returned by ReadTablet (and surfaced by refreshTablets) when a nil tablet alias is passed. The alias is the primary key for looking up a tablet, so a nil value is rejected immediately.
Source
Thrown at go/vt/vtorc/inst/tablet_dao.go:37
import (
"context"
"errors"
"google.golang.org/protobuf/encoding/prototext"
"vitess.io/vitess/go/protoutil"
"vitess.io/vitess/go/vt/external/golib/sqlutils"
replicationdatapb "vitess.io/vitess/go/vt/proto/replicationdata"
topodatapb "vitess.io/vitess/go/vt/proto/topodata"
"vitess.io/vitess/go/vt/topo"
"vitess.io/vitess/go/vt/topo/topoproto"
"vitess.io/vitess/go/vt/vtorc/db"
"vitess.io/vitess/go/vt/vttablet/tmclient"
)
// ErrTabletAliasNil is a fixed error message.
var (
ErrTabletAliasNil = errors.New("tablet alias is nil")
tmc tmclient.TabletManagerClient
)
// InitializeTMC initializes the tablet manager client to use for all VTOrc RPC calls.
func InitializeTMC() tmclient.TabletManagerClient {
tmc = tmclient.NewTabletManagerClient()
return tmc
}
// fullStatus gets the full status of the MySQL running in vttablet.
func fullStatus(tablet *topodatapb.Tablet) (*replicationdatapb.FullStatus, error) {
tmcCtx, tmcCancel := context.WithTimeout(context.Background(), topo.RemoteOperationTimeout)
defer tmcCancel()
return tmc.FullStatus(tmcCtx, tablet)
}
// ReadTablet reads the vitess tablet record.
func ReadTablet(tabletAlias *topodatapb.TabletAlias) (*topodatapb.Tablet, error) {View on GitHub (pinned to 01a25a7d17)
Solutions
- Guard the call site with a nil check on the alias before calling ReadTablet.
- Fix the upstream lookup to return an error instead of a nil alias with nil error.
- Handle the not-yet-elected-primary case explicitly: skip tablets whose shard has no primary alias.
Example fix
// before
t, err := inst.ReadTablet(ctx, alias)
// after
if alias == nil {
return nil, inst.ErrTabletAliasNil
}
t, err := inst.ReadTablet(ctx, alias) Defensive patterns
Strategy: validation
Validate before calling
if alias == nil {
return nil, inst.ErrTabletAliasNil
} Type guard
func hasPrimaryAlias(shard *topo.ShardInfo) bool {
return shard.GetPrimaryAlias() != nil
} Try / catch
t, err := inst.ReadTablet(ctx, alias)
if errors.Is(err, inst.ErrTabletAliasNil) {
log.Warn("tablet read skipped: nil alias (shard may have no primary)")
return nil
} else if err != nil { return err } Prevention
- Check shard.GetPrimaryAlias() for nil before primary-dependent reads.
- Make upstream lookups return errors alongside nil results instead of silent nils.
- Validate aliases (non-nil, non-empty cell/uid) at API boundaries.
When it happens
Trigger: Calling ReadTablet(ctx, nil) — commonly when an upstream topo read or shard-primary lookup returned a nil alias without a corresponding error.
Common situations: Shard records with an empty primary alias (no primary elected yet) being passed to ReadTablet; bugs in tablet enumeration loops; partially loaded topo data.
Related errors
- ReadTopologyInstance will not act on empty tablet alias
- ForgetInstance(): empty tabletAlias
- ReadTopologyInstance(%+v): %+v
- can't lock shard: keyspace is unspecified
- tablet %v type change %v -> %v is not an allowed transition
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/b1a77ac6c7bbf2cf.
Report an issue: GitHub.