kubernetes/kops · error

method DeleteSSHCredential not supported in server-side clie

Error message

method DeleteSSHCredential not supported in server-side client

What it means

The server-side sshCredentialStore does not support deleting SSH credentials; DeleteSSHCredential unconditionally returns this sentinel error. The kops-controller clientset implements only read-oriented credential operations, so any deletion attempt fails immediately without contacting the API server. Callers such as the `kops delete sshpublickey` command path (RunDeleteSSHPublicKey) will surface this error to the user.

Source

Thrown at cmd/kops-controller/pkg/controllerclientset/sshcredentialstore.go:52

var _ fi.SSHCredentialStore = &sshCredentialStore{}

func newSSHCredentialStore(clusterBasePath vfs.Path, cluster *kops.Cluster) *sshCredentialStore {
	if cluster == nil || cluster.Name == "" {
		klog.Fatalf("cluster / cluster.Name is required")
	}

	s := &sshCredentialStore{
		clusterBasePath: clusterBasePath,
		cluster:         cluster,
	}

	return s
}

// DeleteSSHCredential deletes the specified SSH credential.
func (s *sshCredentialStore) DeleteSSHCredential() error {
	return fmt.Errorf("method DeleteSSHCredential not supported in server-side client")
}

// AddSSHPublicKey adds an SSH public key.
func (s *sshCredentialStore) AddSSHPublicKey(ctx context.Context, data []byte) error {
	return fmt.Errorf("method AddSSHPublicKey not supported in server-side client")
}

// FindSSHPublicKeys retrieves the SSH public keys.
func (s *sshCredentialStore) FindSSHPublicKeys() ([]*kops.SSHCredential, error) {
	klog.Warningf("method FindSSHPublicKeys is stub-implemented supported in server-side client")
	return nil, nil
}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Delete the SSH credential secret directly with kubectl (the sshpublickeys.kops.k8s.io secret in the cluster), e.g. `kubectl -n kube-system delete secret sshpublickey.<name>`
  2. Use the standard kops registry (state store) client for credential deletion, which implements DeleteSSHCredential
  3. Rotate keys by adding a new key with the desired name rather than deleting via this client
  4. Contribute a DeleteSSHCredential implementation backed by the Kubernetes secret API in cmd/kops-controller/pkg/controllerclientset/sshcredentialstore.go

Example fix

// before
store, err := serverSideRegistry.SSHCredentialStore(clusterName)
if err != nil { return err }
if err := store.DeleteSSHCredential(); err != nil { return err } // always fails
// after
err = kubectlDelete(ctx, "-n", "kube-system", "secret", "sshpublickey.admin")
Defensive patterns

Strategy: try-catch

Validate before calling

// Detect server-side registry before attempting deletion:
if registry, ok := reg.(*controllerclientset.Registry); ok {
	return fmt.Errorf("SSH credential deletion must go through kubectl or the state-store registry")
}

Type guard

func isServerSideStore(v interface{}) bool {
	_, ok := v.(*controllerclientset.SSHCredentialStoreProxy)
	return ok
}

Try / catch

if err := store.DeleteSSHCredential(); err != nil {
	if strings.Contains(err.Error(), "not supported in server-side client") {
		return kubectl.Delete(ctx, "kube-system", "secret", sshCredentialSecretName)
	}
	return err
}

Prevention

When it happens

Trigger: Running `kops delete sshpublickey` (or programmatic calls to DeleteSSHCredential) against a cluster whose registry is backed by the server-side controller clientset, e.g. when the kops binary is configured to talk to the kops-controller-managed API surface.

Common situations: Operators rotating or revoking SSH access by deleting the sshpublickey secret through the kops CLI while using a server-side registry configuration; automation scripts that clean up old SSH keys; environments migrated from the legacy (S3/state-store) registry to server-side mode.

Related errors


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