kubernetes/kops · error
server-side client does not support StoreKeyset
Error message
server-side client does not support StoreKeyset
What it means
The server-side keystore in kops-controller is a read-only, in-memory implementation of pki.Keystore/fi.CAStore. StoreKeyset is part of the interface it must satisfy, but persisting new keysets is intentionally unsupported in the controller process, so the method unconditionally returns this stub error.
Source
Thrown at cmd/kops-controller/pkg/server/keystore.go:65
entry, ok := k.keys[name]
if !ok {
return nil, nil, fmt.Errorf("unknown CA %q", name)
}
return entry.certificate, entry.key, nil
}
// FindKeyset finds a Keyset. If the keyset is not found, it returns (nil, nil).
func (k *keystore) FindKeyset(ctx context.Context, name string) (*fi.Keyset, error) {
keySet, ok := k.keySets[name]
if !ok {
return nil, nil
}
return keySet, nil
}
// StoreKeyset writes a Keyset to the store.
func (k *keystore) StoreKeyset(ctx context.Context, name string, keyset *fi.Keyset) error {
return fmt.Errorf("server-side client does not support StoreKeyset")
}
// MirrorTo will copy secrets to a vfs.Path, which is often easier for a machine to read
func (k *keystore) MirrorTo(ctx context.Context, basedir vfs.Path) error {
return fmt.Errorf("server-side client does not support MirrorTo")
}
// ListKeysets will return all the KeySets.
func (k *keystore) ListKeysets() (map[string]*fi.Keyset, error) {
return nil, fmt.Errorf("server-side client does not support ListKeysets")
}
func newKeystore(basePath string, cas []string) (*keystore, map[string]string, error) {
keystore := &keystore{
keys: map[string]keystoreEntry{},
keySets: map[string]*fi.Keyset{},
}
for _, name := range cas {View on GitHub (pinned to 4c8573c808)
Solutions
- Do not call StoreKeyset on the server-side keystore; persist keysets through the cluster's regular keystore instead
- If keyset writing is needed in the controller, use a store implementation backed by the cluster state (e.g. vfs-based CAStore)
- Refactor caller to treat the server keystore as read-only and handle the not-supported error explicitly
Example fix
// before
err := serverKeystore.StoreKeyset(ctx, name, keyset)
// after
if err := serverKeystore.StoreKeyset(ctx, name, keyset); err != nil {
// persist via cluster store instead
err = clusterStore.Keystore().StoreKeyset(ctx, name, keyset)
} Defensive patterns
Strategy: validation
Validate before calling
// Detect the read-only server keystore before attempting a write
type readOnlyKeystore interface{ StoreKeyset(ctx context.Context, name string, ks *fi.Keyset) error }
if _, ok := store.(readOnlyKeystore); ok && isServerSideKeystore(store) {
return fmt.Errorf("refusing StoreKeyset on read-only server-side keystore")
} Type guard
func isServerSideKeystore(store pki.Keystore) bool {
_, ro := store.(interface{ MirrorTo(ctx context.Context, p vfs.Path) error })
return ro // server keystore is the only impl lacking write support markers
} Try / catch
if err := ks.StoreKeyset(ctx, name, keyset); err != nil {
if strings.Contains(err.Error(), "does not support StoreKeyset") {
return persistViaClusterStore(ctx, name, keyset)
}
return err
} Prevention
- Treat the kops-controller server keystore as read-only by design
- Persist keysets via the cluster's vfs/etcd-backed CAStore
- Add an interface marker (e.g. ReadOnlyKeystore) so callers can detect write capability
- Never route key-rotation write paths through the controller's in-memory store
When it happens
Trigger: Any code path that calls keystore.StoreKeyset on the server-side keystore — e.g. PKI issue/rotate logic that expects a writable store (like the vfs/cluster-based CAStore) is invoked inside kops-controller.
Common situations: Reusing kops-controller server code with a component that tries to write generated or rotated keysets back to the store; a code refactor routes keyset persistence through the server keystore instead of the cluster store.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- server-side client does not support ListKeysets
- server-side client does not support MirrorTo
- InstanceGroups::Create not supported for server-side client
- InstanceGroups::Update not supported for server-side client
- unknown CA %q
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/f7c19863754d41d8.
Report an issue: GitHub.