kubernetes/kops · error

error updating keyset %q: %v

Error message

error updating keyset %q: %v

What it means

ClientsetCAStore.storeKeyset persists a kops Keyset (CA keys, secret keys, etc.) to the Kubernetes cluster via the kops clientset. When the keyset already exists (create==false) it calls Update; any API error from Update is wrapped as 'error updating keyset %q: %v'. This indicates the kops API server rejected the update of the keyset object.

Source

Thrown at upup/pkg/fi/clientset_castore.go:251

		err = nil
	}
	if err == nil {
		if oldKeyset == nil {
			create = true
		} else {
			kopsKeyset.ObjectMeta = oldKeyset.ObjectMeta
		}
	} else {
		return fmt.Errorf("error reading keyset %q: %v", name, err)
	}

	if create {
		if _, err := client.Create(ctx, kopsKeyset, metav1.CreateOptions{}); err != nil {
			return fmt.Errorf("error creating keyset %q: %v", name, err)
		}
	} else {
		if _, err := client.Update(ctx, kopsKeyset, metav1.UpdateOptions{}); err != nil {
			return fmt.Errorf("error updating keyset %q: %v", name, err)
		}
	}
	return nil
}

// addSSHCredential saves the specified SSH Credential to the registry, doing an update or insert
func (c *ClientsetCAStore) addSSHCredential(ctx context.Context, publicKey string) error {
	create := false
	client := c.clientset.SSHCredentials(c.namespace)
	sshCredential, err := client.Get(ctx, "admin", metav1.GetOptions{})
	if err != nil {
		if errors.IsNotFound(err) {
			sshCredential = nil
		} else {
			return fmt.Errorf("error reading SSHCredential: %v", err)
		}
	}
	if sshCredential == nil {

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Inspect the wrapped %v cause: if it is a conflict, re-run the command so it re-reads and retries the update
  2. Verify RBAC allows create/update on keysets.kops.k8s.io in the kops namespace
  3. Check API server reachability and kubeconfig context (`kubectl get nodes`)
  4. If the keyset is corrupt/missing, delete it and re-run the operation so create path is taken

Example fix

// before (caller ignores conflicts, blind retry fails)
if err := keysetStore.StoreKeyset(ctx, name, keyset); err != nil { return err }
// after (retry once on conflict)
if err := keysetStore.StoreKeyset(ctx, name, keyset); err != nil {
	if strings.Contains(err.Error(), "conflict") {
		time.Sleep(2 * time.Second)
		err = keysetStore.StoreKeyset(ctx, name, keyset)
	}
	if err != nil { return err }
}
Defensive patterns

Strategy: retry

Validate before calling

// pre-check API access
if err := clientset.Keysets(ns).List(ctx, metav1.ListOptions{}); err != nil {
	return fmt.Errorf("no API access for keysets: %w", err)
}

Try / catch

if err := store.StoreKeyset(ctx, name, ks); err != nil {
	if isConflict(err) { time.Sleep(time.Second); err = store.StoreKeyset(ctx, name, ks) }
	if err != nil { return fmt.Errorf("keyset %s persist failed: %w", name, err) }
}

Prevention

When it happens

Trigger: Calling StoreKeyset on a ClientsetCAStore for a keyset that exists but fails Update: API server connectivity failures, RBAC denial on kops Keyset resources, resourceVersion conflict (concurrent writers), invalid object, or namespace missing.

Common situations: kOps CLI run against a cluster where the kops system namespace/state store was partially deleted; concurrent `kops update cluster` runs mutating the same keyset; user kubeconfig lacking permissions to the kops namespace; network partition to the API server during `kops create secret`.

Related errors


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