kubernetes/kops · error
unhandled secret type %q: %v
Error message
unhandled secret type %q: %v
What it means
ListKeysets switches on keyset.Spec.Type; only SecretTypeKeypair is handled and SecretTypeSecret is skipped. Any other Spec.Type hits the default branch and returns 'unhandled secret type "<type>": <underlying>'. Notably the format verb references err (often nil), so the message may show '<nil>'. From upup/pkg/fi/clientset_castore.go:207.
Source
Thrown at upup/pkg/fi/clientset_castore.go:207
if err != nil {
return nil, fmt.Errorf("error listing Keysets: %v", err)
}
for i := range list.Items {
keyset := &list.Items[i]
switch keyset.Spec.Type {
case kops.SecretTypeKeypair:
item, err := parseKeyset(keyset)
if err != nil {
return nil, fmt.Errorf("parsing keyset %q: %w", keyset.Name, err)
}
items[keyset.Name] = item
case kops.SecretTypeSecret:
continue // Ignore - this is handled by ClientsetSecretStore
default:
return nil, fmt.Errorf("unhandled secret type %q: %v", keyset.Spec.Type, err)
}
}
}
return items, nil
}
// StoreKeyset implements CAStore::StoreKeyset
func (c *ClientsetCAStore) StoreKeyset(ctx context.Context, name string, keyset *Keyset) error {
return c.storeKeyset(ctx, name, keyset)
}
// storeKeyset saves the specified keyset to the registry.
func (c *ClientsetCAStore) storeKeyset(ctx context.Context, name string, keyset *Keyset) error {
create := false
client := c.clientset.Keysets(c.namespace)
kopsKeyset, err := keyset.ToAPIObject(name)View on GitHub (pinned to 4c8573c808)
Solutions
- Inspect kubectl get keysets -n <namespace> -o jsonpath='{.items[*].spec.type}' to find the offending object
- Delete or correct the object with the unrecognized spec.type (or move it out of the kops namespace)
- Upgrade kOps to a version that knows the new keyset type instead of downgrading
- Patch ListKeysets to ignore unknown types (continue) rather than erroring if upstream allows
Example fix
// before
default:
return nil, fmt.Errorf("unhandled secret type %q: %v", keyset.Spec.Type, err)
// after
default:
klog.Warningf("skipping keyset %q with unhandled type %q", keyset.Name, keyset.Spec.Type)
continue Defensive patterns
Strategy: type-guard
Validate before calling
types := map[string]bool{"keypair": true, "secret": true}
for _, ks := range allKeysets {
if !types[string(ks.Spec.Type)] {
return fmt.Errorf("keyset %s has unsupported type %q", ks.Name, ks.Spec.Type)
}
} Type guard
func isKnownKeysetType(t kops.SecretType) bool {
return t == kops.SecretTypeKeypair || t == kops.SecretTypeSecret
} Try / catch
items, err := store.ListKeysets()
if err != nil {
if strings.Contains(err.Error(), "unhandled secret type") {
// version mismatch: upgrade kOps or clean stray keysets
}
return err
} Prevention
- Avoid downgrade across kOps versions that add new keyset types
- Never hand-craft Keyset objects with custom spec.type values
- Keep other tooling out of the kops system namespace
When it happens
Trigger: A Keyset object exists in the namespace whose Spec.Type is neither 'keypair' nor 'secret' — e.g. a type introduced by a newer kOps version, or a hand-created object with a wrong/empty type.
Common situations: Rolling back kOps after an upgrade introduced new keyset types; operators copying Keyset YAML by hand with a modified type field; CRD objects from other tooling sharing the namespace.
Related errors
- private key not provided for primary item
- adding keypair to %q is not supported
- promoting keypairs for %q is not supported
- keyset not found
- unhandled sha length for %q
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/5dbd99b71d43751a.
Report an issue: GitHub.