{"record":{"id":"4547259483ccaafd","repo":"vitessio/vitess","slug":"tablet-record-was-taken-over-by-another-process-m","errorCode":null,"errorMessage":"tablet record was taken over by another process: my address is %v:%v, but record is owned by %v:%v","messagePattern":"tablet record was taken over by another process: my address is (.+?):(.+?), but record is owned by (.+?):(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"go/vt/topotools/tablet.go","lineNumber":140,"sourceCode":"\t\ttablet.Type = newType\n\t\ttablet.PrimaryTermStartTime = PrimaryTermStartTime\n\t\treturn nil\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn result, nil\n}\n\n// CheckOwnership returns nil iff the Hostname and port match on oldTablet and\n// newTablet, which implies that no other tablet process has taken over the\n// record.\nfunc CheckOwnership(oldTablet, newTablet *topodatapb.Tablet) error {\n\tif oldTablet == nil || newTablet == nil {\n\t\treturn errors.New(\"unable to verify ownership of tablet record\")\n\t}\n\tif oldTablet.Hostname != newTablet.Hostname || oldTablet.PortMap[\"vt\"] != newTablet.PortMap[\"vt\"] {\n\t\treturn fmt.Errorf(\n\t\t\t\"tablet record was taken over by another process: \"+\n\t\t\t\t\"my address is %v:%v, but record is owned by %v:%v\",\n\t\t\toldTablet.Hostname, oldTablet.PortMap[\"vt\"], newTablet.Hostname, newTablet.PortMap[\"vt\"])\n\t}\n\treturn nil\n}\n\n// DoCellsHaveRdonlyTablets returns true if any of the cells has at least one\n// tablet with type RDONLY. If the slice of cells to search over is empty, it\n// checks all cells in the topo.\nfunc DoCellsHaveRdonlyTablets(ctx context.Context, ts *topo.Server, cells []string) (bool, error) {\n\tareAnyRdonly := func(tablets []*topo.TabletInfo) bool {\n\t\tfor _, tablet := range tablets {\n\t\t\tif tablet.Type == topodatapb.TabletType_RDONLY {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/topotools/tablet.go#L122-L158","documentation":"CheckOwnership verifies that the current process still owns its tablet record in the topo store by comparing hostname and vt port of the locally loaded tablet against the re-fetched record. If either differs, another process has overwritten the record (taken it over, e.g. after a previous instance failed to clean up or a stale process restarted), and this error reports both addresses.","triggerScenarios":"Calling CheckOwnership (from tablet initialization/actions) when the tablet record in the topo has a different Hostname or PortMap[\"vt\"] than the oldTablet passed in — i.e. another vttablet process re-registered the same tablet alias with its own address.","commonSituations":"Starting a second vttablet with the same tablet alias/uid while the first is still running; a container restarted with a new IP/hostname and re-registered the record; stale topo record overwritten by an orphaned process after a crash.","solutions":["Verify no duplicate vttablet process is running with the same tablet alias (ps / container listing); kill the stale one, then re-register.","If the record legitimately changed (hostname/IP moved), restart your vttablet so it reloads the current record or re-initializes with --init_keyspace etc. using the correct topology.","Use vtctldclient to inspect the tablet record and, if it's orphaned, delete or fix it before retrying."],"exampleFix":"// before: assuming ownership\nerr := topotools.CheckOwnership(oldTablet, newTablet)\n// after: detect takeover and bail out loudly\nif err := topotools.CheckOwnership(oldTablet, newTablet); err != nil {\n    log.Errorf(\"tablet %s record taken over, not proceeding\", alias)\n    return err\n}","handlingStrategy":"type-guard","validationCode":"cur, err := ts.GetTablet(ctx, tablet.Alias)\nif err != nil {\n    return fmt.Errorf(\"cannot read current record: %w\", err)\n}\nif cur.Hostname != myHostname || cur.PortMap[\"vt\"] != myPort {\n    return fmt.Errorf(\"record owned by %v:%v; refusing to act\", cur.Hostname, cur.PortMap[\"vt\"])\n}","typeGuard":"func recordTakenOver(oldTablet, newTablet *topodatapb.Tablet) bool {\n    if oldTablet == nil || newTablet == nil {\n        return false\n    }\n    return oldTablet.Hostname != newTablet.Hostname || oldTablet.PortMap[\"vt\"] != newTablet.PortMap[\"vt\"]\n}","tryCatchPattern":"if err := topotools.CheckOwnership(oldTablet, newTablet); err != nil {\n    if strings.Contains(err.Error(), \"taken over by another process\") {\n        log.Error(\"duplicate vttablet suspected; shutting down this instance\")\n        return err // do NOT proceed with actions on a contested record\n    }\n    return err\n}","preventionTips":["Never start two vttablet processes with the same tablet alias/uid","In containerized environments, ensure a fresh IP/hostname does not silently re-register an existing alias — re-init deliberately","Use fencing/health checks to confirm the old process is dead before re-registering a tablet alias"],"tags":["topo","tablet-ownership","tablet-management"],"backgroundTag":"tablet-record-taken-over","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}