kubernetes/kops · error
clientset bound to cluster %q, got cluster %q
Error message
clientset bound to cluster %q, got cluster %q
What it means
The controllerclientset client is bound to a single cluster (set at construction via c.clusterName); GetCluster rejects any requested name that differs. This is a strict name-mismatch guard so a misconfigured caller cannot silently read another cluster's config.
Source
Thrown at cmd/kops-controller/pkg/controllerclientset/clientset.go:58
clusterName: clusterName,
clusterKeystore: clusterKeystore,
clusterSecretStore: clusterSecretStore,
}, nil
}
type client struct {
vfsContext *vfs.VFSContext
clusterBasePath vfs.Path
clusterName string
clusterKeystore fi.CAStore
clusterSecretStore fi.SecretStore
}
// GetCluster reads a cluster by name
func (c *client) GetCluster(ctx context.Context, name string) (*kops.Cluster, error) {
if name != c.clusterName {
return nil, fmt.Errorf("clientset bound to cluster %q, got cluster %q", c.clusterName, name)
}
p := c.clusterBasePath.Join("config")
b, err := p.ReadFile(ctx)
if err != nil {
return nil, fmt.Errorf("reading file %v: %w", p, err)
}
gvk := kops.SchemeGroupVersion.WithKind("Cluster")
object, _, err := kopscodecs.Decode(b, &gvk)
if err != nil {
return nil, fmt.Errorf("error parsing %v: %w", p, err)
}
cluster, ok := object.(*kops.Cluster)
if !ok {
return nil, fmt.Errorf("unexpected kind for cluster, got %T, want kops.Cluster", object)
}View on GitHub (pinned to 4c8573c808)
Solutions
- Use the exact bound cluster name (c.clusterName) in the request
- Construct the clientset with the cluster you intend to query
- Fix the --name/cluster flag passed to the calling command
- Refactor to a multi-cluster clientset if cross-cluster reads are required
Example fix
// before cluster, err := clientset.GetCluster(ctx, "prod.example.com") // bound to dev.example.com // after cluster, err := clientset.GetCluster(ctx, "dev.example.com") // matches bound cluster
Defensive patterns
Strategy: validation
Validate before calling
// before calling GetCluster
if requestedName != boundClusterName {
return fmt.Errorf("refusing GetCluster(%q): clientset bound to %q", requestedName, boundClusterName)
} Type guard
func (c *client) canServe(name string) bool {
return name == c.clusterName
} Try / catch
cluster, err := clientset.GetCluster(ctx, name)
if err != nil {
if strings.Contains(err.Error(), "bound to cluster") {
return fmt.Errorf("wrong clientset for cluster %q", name)
}
return err
} Prevention
- Keep the --name flag consistent with the clientset's bound cluster
- Use the multi-cluster kops CLI state store path for cross-cluster queries
- Avoid iterating cluster lists against a single-cluster clientset
When it happens
Trigger: Calling client.GetCluster(ctx, name) where name != c.clusterName — e.g. RunGetAll/RunGetClusters requesting multiple/other cluster names against a bound, single-cluster clientset.
Common situations: kops get operations iterating over several clusters while the controller clientset was created for one; stale CLI flag (--name) differing from the bound cluster; copy-pasted cluster name or typo.
Related errors
- --name is required
- failed to parse objects: %w
- failed to parse apiVersion %q
- failed to find kind in object
- at least one channel URL is required
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/3b7c9fd6ea262f08.
Report an issue: GitHub.