{"record":{"id":"36aeb8d7c3793404","repo":"vitessio/vitess","slug":"failed-reading-existing-tablet-v-v","errorCode":null,"errorMessage":"failed reading existing tablet %v: %v","messagePattern":"failed reading existing tablet (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/topo/tablet.go","lineNumber":637,"sourceCode":"\t\treturn fmt.Errorf(\"shard %v/%v has a different KeyRange: %v != %v\", tablet.Keyspace, tablet.Shard, si.KeyRange, tablet.KeyRange)\n\t}\n\tif tablet.Type == topodatapb.TabletType_PRIMARY && si.HasPrimary() && !topoproto.TabletAliasEqual(si.PrimaryAlias, tablet.Alias) && !allowPrimaryOverride {\n\t\t// InitTablet is deprecated, so the flag has not been renamed\n\t\treturn 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)\n\t}\n\n\tif tablet.Type == topodatapb.TabletType_PRIMARY {\n\t\t// we update primary_term_start_time even if the primary hasn't changed\n\t\t// because that means a new primary term with the same primary\n\t\ttablet.PrimaryTermStartTime = protoutil.TimeToProto(time.Now())\n\t}\n\n\terr = ts.CreateTablet(ctx, tablet)\n\tif IsErrType(err, NodeExists) && allowUpdate {\n\t\t// Try to update then\n\t\toldTablet, err := ts.GetTablet(ctx, tablet.Alias)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed reading existing tablet %v: %v\", topoproto.TabletAliasString(tablet.Alias), err)\n\t\t}\n\n\t\t// Check we have the same keyspace / shard, and if not,\n\t\t// require the allowDifferentShard flag.\n\t\tif oldTablet.Keyspace != tablet.Keyspace || oldTablet.Shard != tablet.Shard {\n\t\t\treturn 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)\n\t\t}\n\t\toldTablet.Tablet = tablet.CloneVT()\n\t\tif err := ts.UpdateTablet(ctx, oldTablet); err != nil {\n\t\t\treturn fmt.Errorf(\"failed updating tablet %v: %v\", topoproto.TabletAliasString(tablet.Alias), err)\n\t\t}\n\t\treturn nil\n\t}\n\treturn err\n}\n\n// ParseServingTabletType parses the tablet type into the enum, and makes sure\n// that the enum is of serving type (PRIMARY, REPLICA, RDONLY/BATCH).","sourceCodeStart":619,"sourceCodeEnd":655,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/topo/tablet.go#L619-L655","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nts.CreateTablet(ctx, tablet) // with allowUpdate=true\n// after\n// ensure no stale record first\nif err := ts.DeleteTablet(ctx, tablet.Alias); topo.IsErrType(err, topo.NoNode) == false && err != nil {\n    return err\n}\nerr = ts.CreateTablet(ctx, tablet)","handlingStrategy":"retry","validationCode":"exists, err := topo.IsErrType(ts.GetTablet(ctx, alias), topo.NoNode)\nif !exists && err == nil { /* tablet already registered */ }","typeGuard":"func isTopoUnavailable(err error) bool {\n    return err != nil && !topo.IsErrType(err, topo.NodeExists) && !topo.IsErrType(err, topo.NoNode)\n}","tryCatchPattern":"if err := ts.InitTablet(ctx, tablet, false, true, false); err != nil {\n    if strings.Contains(err.Error(), \"failed reading existing tablet\") {\n        // topo read failed; retry with backoff\n    }\n    return err\n}","preventionTips":["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)"],"tags":["topo","tablet-registration","zookeeper"],"backgroundTag":"topo-server-read-failure","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}