vitessio/vitess · error · ErrUnsupportedCluster

%w: %s

Error message

%w: %s

What it means

API.GetVSchemas resolves the requested clusters first; if no clusters match — meaning the caller explicitly passed ClusterIds that do not correspond to any configured cluster — it returns errors.ErrUnsupportedCluster wrapped with the requested IDs via %w. It is a sentinel-wrapped error so callers can errors.Is against ErrUnsupportedCluster.

Source

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

}

// GetVSchemas is part of the vtadminpb.VTAdminServer interface.
func (api *API) GetVSchemas(ctx context.Context, req *vtadminpb.GetVSchemasRequest) (*vtadminpb.GetVSchemasResponse, error) {
	span, ctx := trace.NewSpan(ctx, "API.GetVSchemas")
	defer span.Finish()

	clusters, _ := api.getClustersForRequest(req.ClusterIds)

	var (
		m        sync.Mutex
		wg       sync.WaitGroup
		rec      concurrency.AllErrorRecorder
		vschemas []*vtadminpb.VSchema
	)

	if len(clusters) == 0 {
		if len(req.ClusterIds) > 0 {
			return nil, fmt.Errorf("%w: %s", errors.ErrUnsupportedCluster, strings.Join(req.ClusterIds, ", "))
		}

		return &vtadminpb.GetVSchemasResponse{VSchemas: []*vtadminpb.VSchema{}}, nil
	}

	for _, c := range clusters {
		if !api.authz.IsAuthorized(ctx, c.ID, rbac.VSchemaResource, rbac.GetAction) {
			continue
		}

		wg.Add(1)

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

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

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Check the returned message for the offending cluster IDs and compare against vtadmin's configured clusters (vtadmin config / --clusters flag)
  2. Correct the cluster ID in the request or add the missing cluster to vtadmin's configuration
  3. Handle errors.ErrUnsupportedCluster with errors.Is in clients to distinguish config drift from transient failures
  4. Refresh the client's cluster list from the vtadmin GetClusters API

Example fix

// before: request with stale ID
req := &vtadminpb.GetVSchemasRequest{ClusterIds: []string{"old-cluster"}}
// after: fetch current IDs first and validate
clusters, _ := client.GetClusters(ctx, &vtadminpb.GetClustersRequest{})
ids := clusterIDs(clusters) // ensure "old-cluster" is present before calling GetVSchemas
Defensive patterns

Strategy: validation

Validate before calling

// Go: validate cluster IDs before calling GetVSchemas
clusters, _ := client.GetClusters(ctx, &vtadminpb.GetClustersRequest{})
known := map[string]bool{}
for _, c := range clusters.Clusters {
	known[c.Id] = true
}
for _, id := range req.ClusterIds {
	if !known[id] {
		return fmt.Errorf("unknown cluster id %q", id)
	}
}

Type guard

func isUnsupportedCluster(err error) bool {
	return errors.Is(err, vtadminerrors.ErrUnsupportedCluster)
}

Try / catch

resp, err := client.GetVSchemas(ctx, req)
if err != nil {
	if isUnsupportedCluster(err) {
		// refresh cluster list / fix IDs
	}
	return err
}

Prevention

When it happens

Trigger: Calling GetVSchemas with req.ClusterIds containing IDs that are not configured in vtadmin (typo, renamed cluster, cluster removed from config), resulting in len(clusters)==0 with non-empty ClusterIds.

Common situations: Cluster renamed or decommissioned in vtadmin config while dashboards/scripts still use the old ID; case-sensitivity mismatch in cluster IDs; stale cached cluster list in a client.

Related errors


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