kubernetes/kops · error
encoding service-account keys: %w
Error message
encoding service-account keys: %w
What it means
When building config for an API-server group, the service-account keyset must be encoded to public keys for the API server config. If keysets['service-account'].ToPublicKeys() fails (missing or malformed key material), this error wraps the cause.
Source
Thrown at pkg/nodemodel/nodeupconfigbuilder.go:277
config.KeypairIDs["etcd-client-cilium"] = keysets["etcd-client-cilium"].Primary.Id
}
}
if hasAPIServer {
if err := loadCertificates(keysets, "apiserver-aggregator-ca", config, true); err != nil {
return nil, nil, err
}
if keysets["etcd-clients-ca"] != nil {
if err := loadCertificates(keysets, "etcd-clients-ca", config, true); err != nil {
return nil, nil, err
}
}
config.KeypairIDs["service-account"] = keysets["service-account"].Primary.Id
config.APIServerConfig.EncryptionConfigSecretHash = n.encryptionConfigSecretHash
serviceAccountPublicKeys, err := keysets["service-account"].ToPublicKeys()
if err != nil {
return nil, nil, fmt.Errorf("encoding service-account keys: %w", err)
}
config.APIServerConfig.ServiceAccountPublicKeys = serviceAccountPublicKeys
} else {
for _, key := range []string{"kubelet", "kube-proxy", "kube-router"} {
if keysets[key] != nil {
config.KeypairIDs[key] = keysets[key].Primary.Id
}
}
}
}
if hasAPIServer {
config.ApiserverAdditionalIPs = wellKnownAddresses[wellknownservices.KubeAPIServer]
}
// Set API server address to an IP from the cluster network CIDR
controlPlaneIPs, err := selectControlPlaneIPs(cluster, wellKnownAddresses[wellknownservices.KubeAPIServer])
if err != nil {View on GitHub (pinned to 4c8573c808)
Solutions
- Inspect the wrapped cause; re-create the service-account keyset with 'kops update cluster' or keyset tooling (kops toolbox pki / get keyset)
- Restore the service-account keyset from a backup of the state store if keys were lost
- Run a cluster rolling-update after fixing keys so nodes pick up the corrected keyset
Defensive patterns
Strategy: try-catch
Validate before calling
sa := keysets["service-account"]
if sa == nil || sa.Primary == nil || sa.Primary.Id == "" {
return fmt.Errorf("service-account keyset missing or has no primary")
} Try / catch
pub, err := keysets["service-account"].ToPublicKeys()
if err != nil {
// re-create keyset from state store backup, then retry
return fmt.Errorf("encoding service-account keys: %w", err)
} Prevention
- Back up the state store keysets before key rotations
- Verify keyset integrity with kops get keyset secrets after rotations
- Use one kOps version for all key creation and consumption
- Re-run kops update cluster if the primary key looks stale
When it happens
Trigger: BuildConfig runs on a control-plane/API-server instance group where the 'service-account' keyset exists but its primary key cannot be serialized to public keys (corrupt/absent key data in the keystore).
Common situations: Keyset store (e.g. in the state store) missing the private/primary service-account key; keys created by a different kOps version with incompatible format; interrupted key rotation leaving an empty primary.
Related errors
- keyset %q not found
- certificate %q not found
- private key %q not found
- no keypair ID for %q
- keyset %q not found
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/29901ba3adf9eb32.
Report an issue: GitHub.