kubernetes/kops · error
AsBytes called on nil private key
Error message
AsBytes called on nil private key
What it means
PrivateKey.AsBytes() is a nil-receiver guard: since AsBytes is commonly invoked from Go templates where a nil *PrivateKey can slip through silently, the method explicitly returns this error instead of panicking when called on a nil pointer. It means the code path reached serialization without ever having loaded, generated, or assigned a key.
Source
Thrown at pkg/pki/privatekey.go:96
func (k *PrivateKey) AsString() (string, error) {
// Nicer behaviour because this is called from templates
if k == nil {
return "", fmt.Errorf("AsString called on nil private key")
}
var data bytes.Buffer
_, err := k.WriteTo(&data)
if err != nil {
return "", fmt.Errorf("error writing SSL private key: %v", err)
}
return data.String(), nil
}
func (k *PrivateKey) AsBytes() ([]byte, error) {
// Nicer behaviour because this is called from templates
if k == nil {
return nil, fmt.Errorf("AsBytes called on nil private key")
}
var data bytes.Buffer
_, err := k.WriteTo(&data)
if err != nil {
return nil, fmt.Errorf("error writing SSL PrivateKey: %v", err)
}
return data.Bytes(), nil
}
func (k *PrivateKey) UnmarshalJSON(b []byte) (err error) {
s := ""
if err := json.Unmarshal(b, &s); err == nil {
r, err := parsePEMPrivateKey([]byte(s))
if err != nil {
// Alternative form: Check if base64 encoded
// TODO: Do we need this? I think we need this only on nodeup, but maybe we could just not base64-it?
d, err2 := base64.StdEncoding.DecodeString(s)View on GitHub (pinned to 4c8573c808)
Solutions
- Check for nil before calling: if k == nil or k.Key == nil, generate a key first (GeneratePrivateKey) or return a clear upstream error.
- Verify ParsePEMPrivateKey results: it returns (nil, nil) when input is empty — treat nil key as an error at load time instead of passing it along.
- Ensure the struct field holding *PrivateKey is populated before template rendering / serialization runs.
Example fix
// before
key, _ := pki.ParsePEMPrivateKey(data)
out, _ := key.AsBytes()
// after
key, err := pki.ParsePEMPrivateKey(data)
if err != nil { return err }
if key == nil { return fmt.Errorf("no private key present in input") }
out, err := key.AsBytes()
if err != nil { return err } Defensive patterns
Strategy: type-guard
Validate before calling
if key == nil || key.Key == nil {
return fmt.Errorf("private key not initialized")
} Type guard
func hasKey(k *pki.PrivateKey) bool { return k != nil && k.Key != nil } Try / catch
b, err := key.AsBytes()
if err != nil {
return fmt.Errorf("serializing private key: %w", err)
} Prevention
- Always check the (key, err) pair from ParsePEMPrivateKey — it can return (nil, nil).
- Populate key fields immediately after struct construction, before any template rendering.
- In templates, guard with a nil check before calling AsBytes.
When it happens
Trigger: Calling AsBytes() on a *PrivateKey that is nil, e.g. a struct field never populated after ParsePEMPrivateKey returned (nil, nil) for empty input, or a template referencing {{ .Key.AsBytes }} where .Key was never set.
Common situations: Templating (yaml/gotemplate) rendering of resources whose key material was not generated because generation was skipped in dry-run; callers ignoring that ParsePEMPrivateKey can return a nil key with nil error on empty data; keys dropped during struct copy or partial initialization.
Related errors
- AsString called on nil private key
- error writing SSL private key: %v
- error writing SSL PrivateKey: %v
- unknown private key type: %T
- could not parse private key (unable to decode PEM)
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/898c2ef1b86a67d1.
Report an issue: GitHub.