{"record":{"id":"53fa843f4b663cf9","repo":"vitessio/vitess","slug":"cannot-delete-srvkeyspace-from-cell-v-for-keyspac","errorCode":null,"errorMessage":"cannot delete SrvKeyspace from cell %v for keyspace %v: %w","messagePattern":"cannot delete SrvKeyspace from cell (.+?) for keyspace (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtctl/grpcvtctldserver/server.go","lineNumber":3632,"sourceCode":"\n\tshards, err := s.ts.GetShardNames(ctx, req.Keyspace)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Remove all the shards, serially. Stop immediately if any fail.\n\tfor _, shard := range shards {\n\t\tlog.Info(fmt.Sprintf(\"Removing cell %v from shard %v/%v\", req.Cell, req.Keyspace, shard))\n\t\tif err2 := removeShardCell(ctx, s.ts, req.Cell, req.Keyspace, shard, req.Recursive, req.Force); err2 != nil {\n\t\t\terr = fmt.Errorf(\"cannot remove cell %v from shard %v/%v: %w\", req.Cell, req.Keyspace, shard, err2)\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\t// Last, remove the SrvKeyspace object.\n\tlog.Info(fmt.Sprintf(\"Removing cell %v keyspace %v SrvKeyspace object\", req.Cell, req.Keyspace))\n\tif err = s.ts.DeleteSrvKeyspace(ctx, req.Cell, req.Keyspace); err != nil {\n\t\terr = fmt.Errorf(\"cannot delete SrvKeyspace from cell %v for keyspace %v: %w\", req.Cell, req.Keyspace, err)\n\t\treturn nil, err\n\t}\n\n\treturn &vtctldatapb.RemoveKeyspaceCellResponse{}, nil\n}\n\n// RemoveShardCell is part of the vtctlservicepb.VtctldServer interface.\nfunc (s *VtctldServer) RemoveShardCell(ctx context.Context, req *vtctldatapb.RemoveShardCellRequest) (resp *vtctldatapb.RemoveShardCellResponse, err error) {\n\tspan, ctx := trace.NewSpan(ctx, \"VtctldServer.RemoveShardCell\")\n\tdefer span.Finish()\n\n\tdefer panicHandler(&err)\n\n\tspan.Annotate(\"keyspace\", req.Keyspace)\n\tspan.Annotate(\"shard\", req.ShardName)\n\tspan.Annotate(\"cell\", req.Cell)\n\tspan.Annotate(\"force\", req.Force)\n\tspan.Annotate(\"recursive\", req.Recursive)","sourceCodeStart":3614,"sourceCodeEnd":3650,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtctl/grpcvtctldserver/server.go#L3614-L3650","documentation":"This error wraps a failure from topo.DeleteSrvKeyspace during the RemoveKeyspaceCell vtctld RPC, after all tablets in the cell have been removed. It means the final step of purging the cell-local SrvKeyspace object failed, so the keyspace is only partially removed from that cell.","triggerScenarios":"Calling `vtctldserver RemoveKeyspaceCell` (via `vtctldclient RemoveKeyspaceCell`) when the topo server cannot delete the SrvKeyspace record — e.g. topo connection failure, permission denied, or the node was concurrently deleted.","commonSituations":"Running a cell decommission while the topo (etcd/ZK) is unavailable or flaky; two operators removing the same cell concurrently so the SrvKeyspace is already gone; topo ACLs denying the vtctld identity write access.","solutions":["Verify topo server connectivity and health (etcd/ZK) and retry RemoveKeyspaceCell","Check whether the SrvKeyspace was already deleted — if so the error is stale and the removal effectively succeeded","Inspect topo ACL/credentials for the vtctld identity","Manually verify/clean the leftover SrvKeyspace with topo tools before re-running"],"exampleFix":"// before\nif err = s.ts.DeleteSrvKeyspace(ctx, req.Cell, req.Keyspace); err != nil {\n    err = fmt.Errorf(\"cannot delete SrvKeyspace from cell %v for keyspace %v: %w\", req.Cell, req.Keyspace, err)\n    return nil, err\n}\n// after\nif err = s.ts.DeleteSrvKeyspace(ctx, req.Cell, req.Keyspace); err != nil {\n    if topo.IsErrType(err, topo.NoNode) {\n        log.Warning(\"SrvKeyspace already deleted\")\n    } else {\n        return nil, fmt.Errorf(\"cannot delete SrvKeyspace from cell %v for keyspace %v: %w\", req.Cell, req.Keyspace, err)\n    }\n}","handlingStrategy":"try-catch","validationCode":"// check SrvKeyspace exists in the target cell before removing\nks, err := topoServer.GetSrvKeyspace(ctx, cell, keyspace)\nif err != nil { /* already gone or topo down — decide */ }","typeGuard":null,"tryCatchPattern":"try {\n  vtctldClient.removeKeyspaceCell(keyspace, cell, /* recursive */ true)\n} catch (e) {\n  if (String(e).includes('cannot delete SrvKeyspace')) {\n    // verify topo health, then check if SrvKeyspace already deleted\n    retryOrTreatAsDone()\n  } else { throw e }\n}","preventionTips":["Ensure topo (etcd/ZK) is healthy before decommissioning a cell","Use the --recursive flag so tablets are removed before the SrvKeyspace","Serialize cell-removal operations to avoid concurrent deletions","Verify topo ACLs grant vtctld write access to the cell's keyspace path"],"tags":["topology","topo","keyspace","cell-decommission"],"backgroundTag":"topo-operation-failed","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}