kubernetes/kops · error

error deleting SSHCredential: %v

Error message

error deleting SSHCredential: %v

What it means

deleteSSHCredential issues a DELETE for the 'admin' SSHCredential via the clientset. Any error from Delete (other than success) is wrapped as 'error deleting SSHCredential: %v'. It means the API server refused the delete of the SSH credential object.

Source

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

	sshCredential.Spec.PublicKey = publicKey
	if create {
		if _, err := client.Create(ctx, sshCredential, metav1.CreateOptions{}); err != nil {
			return fmt.Errorf("error creating SSHCredential: %v", err)
		}
	} else {
		if _, err := client.Update(ctx, sshCredential, metav1.UpdateOptions{}); err != nil {
			return fmt.Errorf("error updating SSHCredential: %v", err)
		}
	}
	return nil
}

// deleteSSHCredential deletes the SSHCredential from the registry.
func (c *ClientsetCAStore) deleteSSHCredential(ctx context.Context) error {
	client := c.clientset.SSHCredentials(c.namespace)
	err := client.Delete(ctx, "admin", metav1.DeleteOptions{})
	if err != nil {
		return fmt.Errorf("error deleting SSHCredential: %v", err)
	}
	return nil
}

// AddSSHPublicKey implements CAStore::AddSSHPublicKey
func (c *ClientsetCAStore) AddSSHPublicKey(ctx context.Context, pubkey []byte) error {
	_, _, _, _, err := ssh.ParseAuthorizedKey(pubkey)
	if err != nil {
		return fmt.Errorf("error parsing SSH public key: %v", err)
	}

	return c.addSSHCredential(ctx, strings.TrimSpace(string(pubkey)))
}

// FindSSHPublicKeys implements CAStore::FindSSHPublicKeys
func (c *ClientsetCAStore) FindSSHPublicKeys() ([]*kops.SSHCredential, error) {
	ctx := context.TODO()

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Check if the cause is NotFound — the credential may already be deleted; treat as success
  2. Verify RBAC grants delete on sshcredentials.kops.k8s.io
  3. Check for finalizers on the SSHCredential object via kubectl and clear them
  4. Verify API server health before retrying

Example fix

// before
if err := store.DeleteSSHCredential(ctx); err != nil { return err }
// after
if err := store.DeleteSSHCredential(ctx); err != nil {
	if strings.Contains(err.Error(), "not found") {
		return nil // already deleted
	}
	return err
}
Defensive patterns

Strategy: type-guard

Validate before calling

// check the object exists before deleting
_, err := clientset.SSHCredentials(ns).Get(ctx, "admin", metav1.GetOptions{})
if apierrors.IsNotFound(err) { return nil } // nothing to delete

Type guard

func isNotFound(err error) bool { return apierrors.IsNotFound(err) }

Try / catch

if err := store.DeleteSSHCredential(ctx); err != nil {
	if isNotFound(err) { return nil } // idempotent success
	return err
}

Prevention

When it happens

Trigger: DeleteSSHCredential called while client.Delete(ctx, "admin", ...) fails: object already gone returning non-NotFound error, RBAC denial on delete, finalizers blocking deletion, or API server errors.

Common situations: `kops delete sshpublickey` with insufficient permissions; a Kubernetes finalizer or owner reference preventing deletion; cluster state store out of sync.

Related errors


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