kubernetes/kops · error

cluster DeleteCollection not implemented for vfs store

Error message

cluster DeleteCollection not implemented for vfs store

What it means

The vfs-backed cluster REST client does not implement the DeleteCollection operation. The VFS (file-system) clientset only supports the subset of REST verbs kOps actually uses via the state store, so unsupported methods deliberately return this error. It is a hard capability limit, not a transient failure.

Source

Thrown at pkg/client/simple/vfsclientset/cluster.go:223

	// TODO: Split this out into real version updates / schema changes
	if c.Spec.ConfigStore.Base == "" {
		configBase, err := r.configBase(clusterName)
		if err != nil {
			return nil, fmt.Errorf("error building ConfigStore.Base for cluster: %v", err)
		}
		c.Spec.ConfigStore.Base = configBase.Path()
	}

	return c, nil
}

func (r *ClusterVFS) Delete(name string, options *metav1.DeleteOptions) error {
	return fmt.Errorf("cluster Delete not implemented for vfs store")
}

func (r *ClusterVFS) DeleteCollection(options *metav1.DeleteOptions, listOptions metav1.ListOptions) error {
	return fmt.Errorf("cluster DeleteCollection not implemented for vfs store")
}

func (r *ClusterVFS) Watch(opts metav1.ListOptions) (watch.Interface, error) {
	return nil, fmt.Errorf("cluster Watch not implemented for vfs store")
}

func (r *ClusterVFS) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *api.Cluster, err error) {
	return nil, fmt.Errorf("cluster Patch not implemented for vfs store")
}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Do not call DeleteCollection on a vfs-backed cluster client; delete clusters individually via Delete/Get on the concrete client or the kops CLI (`kops delete cluster`).
  2. List clusters with List()/Find() and loop over names, calling Delete for each, implementing the collection semantics yourself.
  3. If you control the code, add an implementation to ClusterVFS.DeleteCollection following the Delete pattern in vfsclientset.

Example fix

// before
err := clusterClient.DeleteCollection(ctx, metav1.DeleteOptions{}, metav1.ListOptions{})
// after
items, err := clusterClient.List(ctx, metav1.ListOptions{})
if err != nil { return err }
for _, c := range items.Items {
    if err := clusterClient.Delete(ctx, c.ObjectMeta.Name, metav1.DeleteOptions{}); err != nil { return err }
}
Defensive patterns

Strategy: validation

Validate before calling

if _, ok := clusterClient.(interface{ DeleteCollection(metav1.DeleteOptions, metav1.ListOptions) error }); !ok {
    return errors.New("vfs-backed clientset does not support DeleteCollection")
}

Type guard

func supportsDeleteCollection(c interface{}) bool {
    _, ok := c.(interface{ DeleteCollection(*metav1.DeleteOptions, metav1.ListOptions) error })
    return ok
}

Try / catch

if err := client.DeleteCollection(opts, listOpts); err != nil && strings.Contains(err.Error(), "not implemented for vfs store") {
    // fall back to per-object deletes
}

Prevention

When it happens

Trigger: Calling ClusterVFS.DeleteCollection(options, listOptions) — e.g. bulk-deleting clusters through the simple clientset interface against a vfs-backed client.

Common situations: Code written against the generic clientset interface (assuming k8s-style DeleteCollection semantics) run against kOps' vfs store; batch cleanup scripts; controllers reusing the interface for kops Cluster resources.

Related errors


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