{"record":{"id":"d807123e1dc39dbb","repo":"vitessio/vitess","slug":"failed-to-delete-tablet-w","errorCode":null,"errorMessage":"failed to delete tablet: %w","messagePattern":"failed to delete tablet: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtadmin/api.go","lineNumber":697,"sourceCode":"\n\treturn c.DeleteShards(ctx, req.Options)\n}\n\n// DeleteTablet is part of the vtadminpb.VTAdminServer interface.\nfunc (api *API) DeleteTablet(ctx context.Context, req *vtadminpb.DeleteTabletRequest) (*vtadminpb.DeleteTabletResponse, error) {\n\tspan, ctx := trace.NewSpan(ctx, \"API.DeleteTablet\")\n\tdefer span.Finish()\n\n\ttablet, c, err := api.getTabletForAction(ctx, span, rbac.DeleteAction, req.Alias, req.ClusterIds)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif _, err := c.DeleteTablets(ctx, &vtctldatapb.DeleteTabletsRequest{\n\t\tAllowPrimary:  req.AllowPrimary,\n\t\tTabletAliases: []*topodatapb.TabletAlias{tablet.Tablet.Alias},\n\t}); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to delete tablet: %w\", err)\n\t}\n\n\treturn &vtadminpb.DeleteTabletResponse{\n\t\tStatus:  \"ok\",\n\t\tCluster: c.ToProto(),\n\t}, nil\n}\n\n// EmergencyFailoverShard is part of the vtadminpb.VTAdminServer interface.\nfunc (api *API) EmergencyFailoverShard(ctx context.Context, req *vtadminpb.EmergencyFailoverShardRequest) (*vtadminpb.EmergencyFailoverShardResponse, error) {\n\tspan, ctx := trace.NewSpan(ctx, \"API.EmergencyFailoverShard\")\n\tdefer span.Finish()\n\n\tc, err := api.getClusterForRequest(req.ClusterId)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n","sourceCodeStart":679,"sourceCodeEnd":715,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtadmin/api.go#L679-L715","documentation":"VTAdmin's DeleteTablet RPC wraps the underlying cluster error when the vtctld DeleteTablets call fails, producing 'failed to delete tablet: <cause>'. The authorization and tablet lookup succeeded; the failure happened in the vtctld/toposerver layer while removing the tablet record. The cause (after the %w wrap) identifies the actual problem.","triggerScenarios":"Calling DeleteTablet (DELETE /tablet) where the underlying c.DeleteTablets vtctld call errors — e.g. the tablet is still a serving primary and AllowPrimary is false, the tablet record is locked/updated concurrently, vtctld is unreachable, or the tablet alias no longer exists in the topo.","commonSituations":"Trying to delete a serving primary without allow_primary=true; topology inconsistencies after an aborted vtctld operation; network/partition between vtadmin and vtctld; stale vtadmin cache showing a tablet that was already deleted.","solutions":["If deleting a primary, retry with allow_primary=true in the request (after confirming replication is healthy)","Check the wrapped cause: run the equivalent vtctldclient DeleteTablets command to see the detailed vtctld error","Verify vtadmin can reach the cluster's vtctld and that the topo (etcd/zk) is healthy","Refresh the tablet list; if the tablet is already gone, treat the delete as a no-op"],"exampleFix":"// before: fails deleting a primary\nDELETE /api/tablet/zone1-0000000100\n// after\nDELETE /api/tablet/zone1-0000000100?allow_primary=true","handlingStrategy":"try-catch","validationCode":"const tablet = await getTablet(alias);\nif (tablet.tablet.type === 'PRIMARY' && !allowPrimary) {\n  throw new Error('refusing to delete serving primary ' + alias + ' without allow_primary');\n}\nif (!(await topoHasTablet(clusterId, alias))) {\n  console.warn('tablet ' + alias + ' not in topo; delete is a no-op');\n}","typeGuard":"function isTabletDeleteFailure(err: unknown): boolean {\n  return err instanceof Error && err.message.startsWith('failed to delete tablet:');\n}","tryCatchPattern":"try {\n  await deleteTablet(clusterId, alias, { allowPrimary });\n} catch (err) {\n  const cause = String(err).replace('failed to delete tablet: ', '');\n  if (cause.includes('is a primary')) {\n    await deleteTablet(clusterId, alias, { allowPrimary: true });\n  } else if (cause.includes('already deleted') || cause.includes('not found')) {\n    return; // treat as success\n  } else {\n    throw err;\n  }\n}","preventionTips":["Never delete a primary without first verifying replication health and setting allow_primary","Confirm vtadmin's vtctld connectivity before batch tablet deletions","Refresh the tablet cache/list before retrying a failed delete","Read the wrapped cause string to distinguish policy vs topo vs connectivity failures"],"tags":["vtadmin","vtctld","tablet","topology"],"backgroundTag":"tablet-deletion-failed","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}