kubernetes/kops · error

error writing Cluster: %v

Error message

error writing Cluster: %v

What it means

ClusterVFS::Update writes the cluster config with vfs.WriteOptionOnlyIfExists, i.e. it only overwrites an existing cluster record. This error wraps the underlying VFS write failure that is not an IsNotExist condition (those are returned unwrapped).

Source

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

	}

	if old == nil {
		return nil, errors.NewNotFound(schema.GroupResource{Group: api.GroupName, Resource: "Cluster"}, clusterName)
	}

	if err := validation.ValidateClusterUpdate(c, status, old, r.vfsContext).ToAggregate(); err != nil {
		return nil, err
	}

	if !apiequality.Semantic.DeepEqual(old.Spec, c.Spec) {
		c.SetGeneration(old.GetGeneration() + 1)
	}

	if err := r.writeConfig(ctx, c, r.basePath.Join(clusterName, registry.PathCluster), c, vfs.WriteOptionOnlyIfExists); err != nil {
		if os.IsNotExist(err) {
			return nil, err
		}
		return nil, fmt.Errorf("error writing Cluster: %v", err)
	}

	return c, nil
}

// List returns a slice containing all the cluster names
// It skips directories that don't look like clusters
func (r *ClusterVFS) listNames(ctx context.Context) ([]string, error) {
	paths, err := r.basePath.ReadTree(ctx)
	if err != nil {
		return nil, fmt.Errorf("error reading state store: %v", err)
	}

	var keys []string
	for _, p := range paths {
		relativePath, err := vfs.RelativePath(r.basePath, p)
		if err != nil {
			return nil, err

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Inspect the wrapped cause for the real backend error (auth, permission, network)
  2. Confirm the cluster exists first — if not, Update should return the IsNotExist path instead
  3. Retry after restoring credentials/connectivity to the state store
  4. Re-run kops update cluster --yes once the backend is reachable
Defensive patterns

Strategy: retry

Validate before calling

// ensure the cluster exists before Update
existing, err := clusterVFS.Get(ctx, cluster.Name, metav1.GetOptions{})
if err != nil || existing == nil {
	return fmt.Errorf("cluster %q not found; Update requires an existing cluster", cluster.Name)
}

Try / catch

updated, err := clusterVFS.Update(cluster, status)
if err != nil && strings.Contains(err.Error(), "error writing Cluster") {
	if os.IsNotExist(err) {
		return ErrClusterNotFound
	}
	// transient backend failure — retry with backoff
	err = retry.Do(func() error { _, err = clusterVFS.Update(cluster, status); return err })
}

Prevention

When it happens

Trigger: Calling Update on a cluster whose config write fails for reasons other than the file not existing: backend auth failure, permissions, network error to the object store, or serialization/write errors inside writeConfig.

Common situations: Expired cloud credentials during kops update/replace; bucket policies denying put-object; transient network failures to s3/gcs; concurrent modifications conflicting with the OnlyIfExists guard.

Related errors


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