kubernetes/kops · error

method AddSSHPublicKey not supported in server-side client

Error message

method AddSSHPublicKey not supported in server-side client

What it means

The server-side sshCredentialStore cannot add SSH public keys; AddSSHPublicKey always returns this sentinel error. This is hit by several kops create/update/replace flows (RunCreate, RunCreateCluster, RunCreateSSHPublicKey, RunReplace, RunUpdateCluster, and cluster creation) whenever they attempt to upload an SSH public key to a server-side registry. No key material is written and the invoking kops command fails.

Source

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

		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. Create the sshpublickey secret directly with kubectl: `kubectl -n kube-system create secret generic sshpublickey.admin --from-file=...`
  2. Upload the key via the standard kops state-store registry client (e.g. run kops with the legacy registry configured) before switching to server-side mode
  3. Pre-provision SSH credentials during cluster bootstrap (cloud-init / nodeup configuration) instead of uploading through this client
  4. Implement AddSSHPublicKey in cmd/kops-controller/pkg/controllerclientset/sshcredentialstore.go backed by the secret API

Example fix

// before
store, err := registry.SSHCredentialStore(clusterName)
if err != nil { return err }
if err := store.AddSSHPublicKey(ctx, keyBytes); err != nil { return err } // fails on server-side client
// after
err = kubectlCreateSecret(ctx, "kube-system", "sshpublickey.admin", keyBytes)
Defensive patterns

Strategy: try-catch

Validate before calling

// Refuse key upload early when the registry is the server-side clientset:
if isServerSideRegistry(registry) {
	return fmt.Errorf("AddSSHPublicKey unsupported: create the sshpublickey secret with kubectl instead")
}

Type guard

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

Try / catch

if err := store.AddSSHPublicKey(ctx, keyBytes); err != nil {
	if strings.Contains(err.Error(), "not supported in server-side client") {
		return kubectl.CreateSecret(ctx, "kube-system", "sshpublickey."+keyName, keyBytes)
	}
	return err
}

Prevention

When it happens

Trigger: Calling AddSSHPublicKey on a server-side-backed registry, i.e. running `kops create cluster --ssh-public-key ...`, `kops create sshpublickey`, `kops replace`, `kops update cluster` with key upload, against a cluster configured for the server-side controller registry.

Common situations: Creating a new cluster while pointing at a server-side registry; re-running `kops update cluster` after adding --ssh-public-key; CI pipelines that provision clusters and upload keys in one step; users who migrated state from S3 state store to the server-side mode and now can't upload keys.

Related errors


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