kubernetes/kops · error

InstanceGroups::Create not supported for server-side client

Error message

InstanceGroups::Create not supported for server-side client

What it means

The server-side clientset intentionally does not support creating InstanceGroups: the in-cluster kops-controller API only exposes read-only list/get plus limited flows. Calling Create always fails here, by design.

Source

Thrown at cmd/kops-controller/pkg/controllerclientset/instancegroups.go:100

	}
	ig.ObjectMeta.Labels[kopsapi.LabelClusterName] = c.clusterName
}

func (c *instanceGroups) List(ctx context.Context, options metav1.ListOptions) (*kopsapi.InstanceGroupList, error) {
	list := &kopsapi.InstanceGroupList{}
	items, err := c.base.List(ctx, list.Items, options)
	if err != nil {
		return nil, err
	}
	list.Items = items.([]kopsapi.InstanceGroup)
	for i := range list.Items {
		c.addLabels(&list.Items[i])
	}
	return list, nil
}

func (c *instanceGroups) Create(ctx context.Context, g *kopsapi.InstanceGroup, opts metav1.CreateOptions) (*kopsapi.InstanceGroup, error) {
	return nil, fmt.Errorf("InstanceGroups::Create not supported for server-side client")
}

func (c *instanceGroups) Update(ctx context.Context, g *kopsapi.InstanceGroup, opts metav1.UpdateOptions) (*kopsapi.InstanceGroup, error) {
	return nil, fmt.Errorf("InstanceGroups::Update not supported for server-side client")
}

func (c *instanceGroups) Delete(ctx context.Context, name string, options metav1.DeleteOptions) error {
	return fmt.Errorf("InstanceGroups::Delete not supported for server-side client")
}

func (r *instanceGroups) DeleteCollection(ctx context.Context, options metav1.DeleteOptions, listOptions metav1.ListOptions) error {
	return fmt.Errorf("InstanceGroups::DeleteCollection not supported for server-side client")
}

func (r *instanceGroups) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) {
	return nil, fmt.Errorf("InstanceGroups::Watch not supported for server-side client")
}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Create instance groups via `kops create ig`/`kops replace -f ig.yaml` and let the controller only observe them
  2. Use a VFS-backed clientset in a CLI/tool context if programmatic creation is required
  3. Refactor the controller to treat instance groups as immutable inputs

Example fix

// before
ig, err := igs.Create(ctx, newInstanceGroup, metav1.CreateOptions{})
// after
// $ kops create -f ig.yaml --name mycluster.example.com
ig, err := igs.Get(ctx, "nodes", metav1.GetOptions{})
Defensive patterns

Strategy: try-catch

Validate before calling

if isReadOnlyInstanceGroupClient(igs) {
  return errors.New("instance group creation must go through the kops CLI or a VFS-backed clientset")
}

Try / catch

ig, err := igs.Create(ctx, g, metav1.CreateOptions{})
if err != nil && strings.Contains(err.Error(), "Create not supported") {
  // write ig.yaml and shell out: kops create -f ig.yaml --name <cluster>
  return createInstanceGroupViaCLI(ctx, g)
}

Prevention

When it happens

Trigger: Calling instanceGroups.Create(ctx, ig, metav1.CreateOptions{}) on the controller's instance group interface, e.g. from code that provisioned node pools on the fly.

Common situations: Reusing CLI autoscaling/rolling-update code inside the controller; attempting dynamic node pool creation from a controller reconciliation loop.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/f12b044034fccbc4. Report an issue: GitHub.