{"record":{"id":"30fb8c325d4e5ff8","repo":"vitessio/vitess","slug":"getcellinfonames-failed-to-acquire-toporeadpool","errorCode":null,"errorMessage":"GetCellInfoNames() failed to acquire topoReadPool: %w","messagePattern":"GetCellInfoNames\\(\\) failed to acquire topoReadPool: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"go/vt/vtadmin/cluster/cluster.go","lineNumber":1054,"sourceCode":"}\n\n// GetCellInfos returns a list of ClusterCellInfo objects for cells in the\n// given cluster.\n//\n// If req.Cells is set, cells are restricted only to cells with those names.\n// Note: specifying a cell name that does not exist in the cluster fails the\n// overall request.\n//\n// If req.NamesOnly is set, each ClusterCellInfo will only contain the Cluster\n// and Name fields. req.Cells takes precedence over this option.\nfunc (c *Cluster) GetCellInfos(ctx context.Context, req *vtadminpb.GetCellInfosRequest) ([]*vtadminpb.ClusterCellInfo, error) {\n\tspan, ctx := trace.NewSpan(ctx, \"Cluster.GetCellInfos\")\n\tdefer span.Finish()\n\n\tnames := req.Cells\n\tif len(names) == 0 {\n\t\tif err := c.topoReadPool.Acquire(ctx); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"GetCellInfoNames() failed to acquire topoReadPool: %w\", err)\n\t\t}\n\t\tresp, err := c.Vtctld.GetCellInfoNames(ctx, &vtctldatapb.GetCellInfoNamesRequest{})\n\t\tc.topoReadPool.Release()\n\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to GetCellInfoNames: %w\", err)\n\t\t}\n\n\t\tnames = resp.Names\n\t}\n\n\tnamesOnly := req.NamesOnly\n\tif namesOnly && len(req.Cells) > 0 {\n\t\tlog.Warn(\"Cluster.GetCellInfos: req.Cells and req.NamesOnly set, ignoring NamesOnly\")\n\t\tnamesOnly = false\n\t}\n\n\tspan.Annotate(\"names_only\", namesOnly)","sourceCodeStart":1036,"sourceCodeEnd":1072,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtadmin/cluster/cluster.go#L1036-L1072","documentation":"GetCellInfos needs the list of cell names when the caller did not supply any, so it takes a topoReadPool slot before calling GetCellInfoNames. If Acquire fails (context done while waiting), the whole call returns this error instead of proceeding to the vtctld RPC.","triggerScenarios":"Calling GetCellInfos with an empty req.Cells while topoReadPool is exhausted and ctx is canceled/deadlined during Acquire.","commonSituations":"Dashboards listing all cells concurrently; small topo pool under burst load; request deadline shorter than pool wait time.","solutions":["Retry with a longer deadline","Increase topoReadPool size","Pass explicit cell names in the request to skip the pool-gated name lookup","Reduce concurrent cell-info requests"],"exampleFix":"// before (caller had no cells, hit pool wait)\nreq := &vtadminpb.GetCellInfosRequest{}\n// after: supply cells to avoid the name-listing path\nreq := &vtadminpb.GetCellInfosRequest{Cells: []string{\"zone1\", \"zone2\"}}","handlingStrategy":"fallback","validationCode":"// avoid the pool-gated path by supplying cell names explicitly\nreq := &vtadminpb.GetCellInfosRequest{Cells: knownCells} // len(req.Cells) > 0 skips Acquire","typeGuard":null,"tryCatchPattern":"cells, err := cluster.GetCellInfos(ctx, req)\nif err != nil && strings.Contains(err.Error(), \"topoReadPool\") {\n    // retry with longer ctx or pass Cells explicitly\n}","preventionTips":["Pass explicit cell names when they are known","Size topoReadPool for concurrent topo reads","Use realistic request deadlines","Cache cell-name lists client-side"],"tags":["vtadmin","semaphore","topology","timeout"],"backgroundTag":"semaphore-acquire-cancelled","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}