kubernetes/kops · error

server-side client does not support MirrorTo

Error message

server-side client does not support MirrorTo

What it means

MirrorTo copies keystore secrets to a vfs.Path for machine consumption; the server-side kops-controller keystore does not implement it and always returns this stub error, because mirroring secrets is a client-side/operator concern, not something the in-memory server store supports.

Source

Thrown at cmd/kops-controller/pkg/server/keystore.go:70

}

// 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 {
		certBytes, err := os.ReadFile(path.Join(basePath, name+".crt"))
		if err != nil {
			return nil, nil, fmt.Errorf("reading %q certificate: %v", name, err)
		}
		// TODO: Support multiple certificates?

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Avoid MirrorTo on the server-side keystore; use the cluster/vfs-backed keystore for mirroring
  2. If a mirror target is required in the controller, load the needed material directly from the controller's PKI basePath files
  3. Handle the error explicitly and skip mirroring when running server-side

Example fix

// before
err := ks.MirrorTo(ctx, vfsPath)

// after
if err := ks.MirrorTo(ctx, vfsPath); err != nil && strings.Contains(err.Error(), "does not support MirrorTo") {
	// server-side store: read required material from basePath instead
}
Defensive patterns

Strategy: validation

Validate before calling

// Skip mirroring when operating against the server-side keystore
if isServerSideKeystore(ks) {
	klog.V(2).Infof("skipping MirrorTo: server-side keystore does not support mirroring")
	return nil
}

Type guard

func isServerSideKeystore(store pki.Keystore) bool {
	_, ro := store.(interface{ ListKeysets() (map[string]*fi.Keyset, error) })
	return ro
}

Try / catch

if err := ks.MirrorTo(ctx, basedir); err != nil {
	if strings.Contains(err.Error(), "does not support MirrorTo") {
		return mirrorFromPKIDir(ctx, basePath, basedir) // copy files directly
	}
	return err
}

Prevention

When it happens

Trigger: Any call to keystore.MirrorTo on the server-side keystore — e.g. code that renders/mirrors keystore contents to a vfs path (such as nodeup/protokube style MirrorTo flows) reaching the Render path that uses this store.

Common situations: Running code that normally mirrors secrets from the cluster CA store inside the controller; template/render code (Render) invoking MirrorTo against the read-only server keystore.

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


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