{"record":{"id":"04504c26fe16549b","repo":"vitessio/vitess","slug":"tablet-v-type-change-v-v-is-not-an-allowed-t","errorCode":null,"errorMessage":"tablet %v type change %v -> %v is not an allowed transition for ChangeTabletType","messagePattern":"tablet (.+?) type change (.+?) -> (.+?) is not an allowed transition for ChangeTabletType","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtctl/grpcvtctldserver/server.go","lineNumber":665,"sourceCode":"\n\tdefer panicHandler(&err)\n\n\tspan.Annotate(\"tablet_alias\", topoproto.TabletAliasString(req.TabletAlias))\n\tspan.Annotate(\"dry_run\", req.DryRun)\n\tspan.Annotate(\"tablet_type\", topoproto.TabletTypeLString(req.DbType))\n\n\tctx, cancel := context.WithTimeout(ctx, topo.RemoteOperationTimeout)\n\tdefer cancel()\n\n\ttablet, err := s.ts.GetTablet(ctx, req.TabletAlias)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tspan.Annotate(\"before_tablet_type\", topoproto.TabletTypeLString(tablet.Type))\n\n\tif !topo.IsTrivialTypeChange(tablet.Type, req.DbType) {\n\t\terr = fmt.Errorf(\"tablet %v type change %v -> %v is not an allowed transition for ChangeTabletType\", req.TabletAlias, tablet.Type, req.DbType)\n\t\treturn nil, err\n\t}\n\n\tif req.DryRun {\n\t\tafterTablet := tablet.CloneVT()\n\t\tafterTablet.Type = req.DbType\n\n\t\treturn &vtctldatapb.ChangeTabletTypeResponse{\n\t\t\tBeforeTablet: tablet.Tablet,\n\t\t\tAfterTablet:  afterTablet,\n\t\t\tWasDryRun:    true,\n\t\t}, nil\n\t}\n\n\tshard, err := s.ts.GetShard(ctx, tablet.Keyspace, tablet.Shard)\n\tif err != nil {\n\t\treturn nil, err\n\t}","sourceCodeStart":647,"sourceCodeEnd":683,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtctl/grpcvtctldserver/server.go#L647-L683","documentation":"ChangeTabletType only permits 'trivial' type transitions (e.g. replica->rdonly or rdonly->replica) because the vttablet process must be restarted for non-trivial type changes. When the requested target type (req.DbType) is not a trivial transition from the tablet's current type, the vtctld server rejects the request with this plain fmt.Errorf before contacting the tablet.","triggerScenarios":"Calling vtctldserver ChangeTabletType with a DbType such as PRIMARY, SPARE, or another non-trivial transition from the tablet's current type; e.g. changing a replica to PRIMARY via ChangeTabletType instead of PlannedReparentShard.","commonSituations":"Scripts or operators using ChangeTabletType to promote/demote primaries; automation written against older Vitess where more transitions were allowed; mixing up ChangeTabletType with Reparenting workflows.","solutions":["Use the appropriate workflow instead: PlannedReparentShard or EmergencyReparentShard for primary changes","Only use ChangeTabletType for trivial transitions between REPLICA and RDONLY","Check topoproto.IsTrivialTypeChange(current, target) client-side before calling","If the tablet's recorded type is stale, fix the topology record first (e.g. via TabletExternallyReparented or deleting/re-adding the tablet record)"],"exampleFix":"// before\nclient.ChangeTabletType(ctx, alias, topodatapb.TabletType_PRIMARY)\n// after\nclient.PlannedReparentShard(ctx, \"commerce\", \"0\", alias)","handlingStrategy":"validation","validationCode":"if !topo.IsTrivialTypeChange(tablet.Type, reqType) {\n    return fmt.Errorf(\"use PlannedReparentShard for %v -> %v\", tablet.Type, reqType)\n}","typeGuard":"func isTrivialTransition(from, to topodatapb.TabletType) bool { return topo.IsTrivialTypeChange(from, to) }","tryCatchPattern":"resp, err := client.ChangeTabletType(ctx, alias, tt)\nif err != nil && strings.Contains(err.Error(), \"not an allowed transition\") {\n    // fall back to PlannedReparentShard\n}","preventionTips":["Only use ChangeTabletType for REPLICA<->RDONLY transitions","Use PlannedReparentShard/EmergencyReparentShard for primary changes","Pre-check IsTrivialTypeChange before the RPC","Keep tablet topology records in sync with reality"],"tags":["vitess","tablet","topology","validation"],"backgroundTag":"invalid-tablet-type-transition","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}