vitessio/vitess · error

GetKeyspaces(cluster = %s): %w

Error message

GetKeyspaces(cluster = %s): %w

What it means

Within GetVSchemas, each cluster's keyspaces are fetched through that cluster's vtctld (c.Vtctld.GetKeyspaces). A failure is recorded per cluster with this wrapper including the cluster ID and the underlying vtctld error; that cluster contributes no keyspaces and the overall request errors via the recorder.

Source

Thrown at go/vt/vtadmin/api.go:1651

			continue
		}

		wg.Add(1)

		go func(c *cluster.Cluster) {
			defer wg.Done()

			span, ctx := trace.NewSpan(ctx, "Cluster.GetVSchemas")
			defer span.Finish()

			cluster.AnnotateSpan(c, span)

			getKeyspacesSpan, getKeyspacesCtx := trace.NewSpan(ctx, "Cluster.GetKeyspaces")
			cluster.AnnotateSpan(c, getKeyspacesSpan)

			keyspaces, err := c.Vtctld.GetKeyspaces(getKeyspacesCtx, &vtctldatapb.GetKeyspacesRequest{})
			if err != nil {
				rec.RecordError(fmt.Errorf("GetKeyspaces(cluster = %s): %w", c.ID, err))
				getKeyspacesSpan.Finish()
				return
			}

			getKeyspacesSpan.Finish()

			var (
				clusterM        sync.Mutex
				clusterWG       sync.WaitGroup
				clusterRec      concurrency.AllErrorRecorder
				clusterVSchemas = make([]*vtadminpb.VSchema, 0, len(keyspaces.Keyspaces))
			)

			for _, keyspace := range keyspaces.Keyspaces {
				clusterWG.Add(1)

				go func(keyspace *vtctldatapb.Keyspace) {
					defer clusterWG.Done()

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Check the wrapped cause for the root gRPC/topo error and the failing cluster ID
  2. Confirm vtctld for that cluster is healthy (vtctldclient GetKeyspaces)
  3. Verify network connectivity and timeouts between vtadmin and vtctld
  4. Retry after restoring topo/vtctld health; consider per-cluster isolation if one bad cluster blocks aggregation

Example fix

// before
keyspaces, err := c.Vtctld.GetKeyspaces(getKeyspacesCtx, &vtctldatapb.GetKeyspacesRequest{})
if err != nil {
	rec.RecordError(fmt.Errorf("GetKeyspaces(cluster = %s): %w", c.ID, err))
	getKeyspacesSpan.Finish()
	return
}
// after: ensure vtctld reachable; add per-cluster timeout
keyspaces, err := c.Vtctld.GetKeyspaces(getKeyspacesCtx, &vtctldatapb.GetKeyspacesRequest{})
if err != nil {
	rec.RecordError(fmt.Errorf("GetKeyspaces(cluster = %s): %w", c.ID, err))
	getKeyspacesSpan.Finish()
	return
}
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-check vtctld GetKeyspaces for the cluster
_, err := c.Vtctld.GetKeyspaces(ctx, &vtctldatapb.GetKeyspacesRequest{})
if err != nil {
	log.Printf("cluster %s vtctld unavailable: %v", c.ID, err)
}

Type guard

func keyspaceFetchFailed(rec concurrency.AllErrorRecorder) bool { return rec.HasErrors() }

Try / catch

resp, err := client.GetVSchemas(ctx, req)
if err != nil {
	if strings.Contains(err.Error(), "GetKeyspaces(cluster = ") {
		// retry after vtctld/topo health restored
	}
	return err
}

Prevention

When it happens

Trigger: Calling GetVSchemas when a cluster's vtctld GetKeyspaces RPC fails — vtctld down, network partition, topo unavailable, or gRPC auth/context cancellation.

Common situations: vtctld restarted mid-request; firewall/network change between vtadmin and vtctld; topo store outage; context deadline exceeded under load.

Related errors


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/d972abbf27b56a22. Report an issue: GitHub.