kubernetes/kops · error
unknown format for private key: %q
Error message
unknown format for private key: %q
What it means
PrivateKey.UnmarshalJSON expects the JSON value to be a string (PEM or base64-encoded PEM). If json.Unmarshal into a string fails, the library has no other supported representation and returns 'unknown format for private key' quoting the raw JSON bytes.
Source
Thrown at pkg/pki/privatekey.go:132
d, err2 := base64.StdEncoding.DecodeString(s)
if err2 == nil {
r2, err2 := parsePEMPrivateKey(d)
if err2 == nil {
klog.Warningf("used base64 decode of PrivateKey")
r = r2
err = nil
}
}
if err != nil {
return fmt.Errorf("error parsing private key: %v", err)
}
}
k.Key = r
return nil
}
return fmt.Errorf("unknown format for private key: %q", string(b))
}
func (k *PrivateKey) MarshalJSON() ([]byte, error) {
var data bytes.Buffer
_, err := k.WriteTo(&data)
if err != nil {
return nil, fmt.Errorf("error writing SSL private key: %v", err)
}
return json.Marshal(data.String())
}
var _ io.WriterTo = &PrivateKey{}
func (k *PrivateKey) WriteTo(w io.Writer) (int64, error) {
if k.Key == nil {
// For the dry-run case
return 0, nil
}View on GitHub (pinned to 4c8573c808)
Solutions
- Ensure the JSON value for the key field is a double-quoted string containing the PEM text (newlines escaped as \n).
- If your source is a raw key file, marshal it as a string first: json.Marshal(string(pemBytes)).
- Check the producer of the JSON (state store, template) for changed serialization format between versions.
Example fix
// before
json.Unmarshal(b, &k) with b = '{"pem": "-----BEGIN..."}'
// after
b, _ := json.Marshal(string(pemBytes)) // "-----BEGIN RSA PRIVATE KEY-----\n..."
json.Unmarshal(b, &k) Defensive patterns
Strategy: validation
Validate before calling
var s string
if err := json.Unmarshal(b, &s); err != nil {
return fmt.Errorf("private key JSON must be a string, got: %s", string(b))
} Try / catch
if err := json.Unmarshal(b, &spec); err != nil {
if strings.Contains(err.Error(), "unknown format for private key") {
// producer emitted a non-string JSON value for the key field
}
return err
} Prevention
- Always marshal keys as plain JSON strings (json.Marshal(string(pemBytes))).
- Check the version of the tool writing the state store when format errors appear after a migration.
- Validate JSON schema of generated specs before applying them.
When it happens
Trigger: Feeding UnmarshalJSON a JSON object, array, number, or null instead of a string — e.g. the key stored as {"data": ...} in the state store, or a field that got double-encoded/unexpectedly typed.
Common situations: Migrating cluster state between kops versions or tools that serialize keys as objects; accidental quoting mistakes producing raw non-string JSON; generating spec files programmatically and marshaling a map instead of the key string.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- unmarshalling authorization token data: %w
- error parsing private key: %v
- error parsing version spec %q
- error encoding version spec: %v
- error building annotation patch: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/4680509611c35ab0.
Report an issue: GitHub.