vitessio/vitess · error
failed reading existing tablet %v: %v
Error message
failed reading existing tablet %v: %v
What it means
InitTablet attempted to create a tablet that already exists in the topo server (NodeExists) with allowUpdate=true, so it fell back to reading the existing tablet record. That read itself failed, so the update path cannot proceed. This is a topo-server connectivity/consistency failure surfaced during the create-then-update fallback.
Source
Thrown at go/vt/topo/tablet.go:637
return fmt.Errorf("shard %v/%v has a different KeyRange: %v != %v", tablet.Keyspace, tablet.Shard, si.KeyRange, tablet.KeyRange)
}
if tablet.Type == topodatapb.TabletType_PRIMARY && si.HasPrimary() && !topoproto.TabletAliasEqual(si.PrimaryAlias, tablet.Alias) && !allowPrimaryOverride {
// InitTablet is deprecated, so the flag has not been renamed
return fmt.Errorf("creating this tablet would override old primary %v in shard %v/%v, use allow_master_override flag", topoproto.TabletAliasString(si.PrimaryAlias), tablet.Keyspace, tablet.Shard)
}
if tablet.Type == topodatapb.TabletType_PRIMARY {
// we update primary_term_start_time even if the primary hasn't changed
// because that means a new primary term with the same primary
tablet.PrimaryTermStartTime = protoutil.TimeToProto(time.Now())
}
err = ts.CreateTablet(ctx, tablet)
if IsErrType(err, NodeExists) && allowUpdate {
// Try to update then
oldTablet, err := ts.GetTablet(ctx, tablet.Alias)
if err != nil {
return fmt.Errorf("failed reading existing tablet %v: %v", topoproto.TabletAliasString(tablet.Alias), err)
}
// Check we have the same keyspace / shard, and if not,
// require the allowDifferentShard flag.
if oldTablet.Keyspace != tablet.Keyspace || oldTablet.Shard != tablet.Shard {
return fmt.Errorf("old tablet has shard %v/%v. Cannot override with shard %v/%v. Delete and re-add tablet if you want to change the tablet's keyspace/shard", oldTablet.Keyspace, oldTablet.Shard, tablet.Keyspace, tablet.Shard)
}
oldTablet.Tablet = tablet.CloneVT()
if err := ts.UpdateTablet(ctx, oldTablet); err != nil {
return fmt.Errorf("failed updating tablet %v: %v", topoproto.TabletAliasString(tablet.Alias), err)
}
return nil
}
return err
}
// ParseServingTabletType parses the tablet type into the enum, and makes sure
// that the enum is of serving type (PRIMARY, REPLICA, RDONLY/BATCH).View on GitHub (pinned to 01a25a7d17)
Solutions
- Check topo server connectivity (vtctld/vttablet flags: -topo_implementation, -topo_global_server_address, -topo_global_root) and retry
- Verify the tablet alias exists: vtctldclient GetTablet <alias>, or delete it first with DeleteTablet if it is stale
- Check topo server permissions/ACLs allow reading tablets/
- If racing deletes, re-run InitTablet once the topo state is stable
Example fix
// before
ts.CreateTablet(ctx, tablet) // with allowUpdate=true
// after
// ensure no stale record first
if err := ts.DeleteTablet(ctx, tablet.Alias); topo.IsErrType(err, topo.NoNode) == false && err != nil {
return err
}
err = ts.CreateTablet(ctx, tablet) Defensive patterns
Strategy: retry
Validate before calling
exists, err := topo.IsErrType(ts.GetTablet(ctx, alias), topo.NoNode)
if !exists && err == nil { /* tablet already registered */ } Type guard
func isTopoUnavailable(err error) bool {
return err != nil && !topo.IsErrType(err, topo.NodeExists) && !topo.IsErrType(err, topo.NoNode)
} Try / catch
if err := ts.InitTablet(ctx, tablet, false, true, false); err != nil {
if strings.Contains(err.Error(), "failed reading existing tablet") {
// topo read failed; retry with backoff
}
return err
} Prevention
- Verify topo server flags/connectivity before tablet startup
- Clean up stale tablet records before re-registering aliases
- Ensure a single vttablet process per alias
- Monitor topo server health (zookeeper quorum/etcd)
When it happens
Trigger: Calling InitTablet (directly or via NewFakeTablet/addTablet) when the tablet node already exists, allowUpdate is true, and ts.GetTablet fails — e.g. the topo server is unreachable, the tablet was deleted between CreateTablet and GetTablet, or permissions block the read.
Common situations: Re-registering a tablet whose alias already exists during vttablet startup; flaky zookeeper/etcd2 connections in test setups using NewFakeTablet; topo data removed concurrently by an operator or cleanup script.
Related errors
- old tablet has shard %v/%v. Cannot override with shard %v/%v
- failed updating tablet %v: %v
- DeleteRecursive: nodes getting recreated underneath delete (
- obtainQueueLock: empty queue node: %v
- obtainQueueLock: no previous queue node found: %v
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/36aeb8d7c3793404.
Report an issue: GitHub.