kubernetes/kops · error
error serializing secret: %v
Error message
error serializing secret: %v
What it means
createSecret persists a *fi.Secret by JSON-marshaling it before writing to VFS. If json.Marshal fails, the error is wrapped as 'error serializing secret'. fi.Secret holds opaque Data ([]byte, base64-encoded by encoding/json) so this is rare, and indicates the in-memory Secret value cannot be represented as JSON.
Source
Thrown at upup/pkg/fi/secrets/vfs_secretstore.go:183
err = createSecret(ctx, secret, p, acl, true)
if err != nil {
return nil, fmt.Errorf("unable to write secret: %v", err)
}
// Confirm the secret exists
s, err := c.loadSecret(ctx, p)
if err != nil {
return nil, fmt.Errorf("unable to load secret immediately after creation %v: %v", p, err)
}
return s, nil
}
// createSecret will create the Secret, overwriting an existing secret if replace is true
func createSecret(ctx context.Context, s *fi.Secret, p vfs.Path, acl vfs.ACL, replace bool) error {
data, err := json.Marshal(s)
if err != nil {
return fmt.Errorf("error serializing secret: %v", err)
}
rs := bytes.NewReader(data)
if replace {
return p.WriteFile(ctx, rs, acl)
}
return p.CreateFile(ctx, rs, acl)
}
View on GitHub (pinned to 4c8573c808)
Solutions
- Construct secrets with fi.NewSecret(data) instead of building the struct literally
- Inspect the wrapped %v marshal cause for the offending field type
- Print/validate the fi.Secret payload before calling ReplaceSecret/GetOrCreateSecret
- If it came from a corrupt source, re-create the secret from known-good data
Example fix
// before
s := &fi.Secret{Data: data, Type: t} // may hold invalid state
err := store.ReplaceSecret(id, s) // error serializing secret: ...
// after
s := fi.NewSecret(data)
s.Type = t
err := store.ReplaceSecret(id, s) Defensive patterns
Strategy: validation
Validate before calling
// Round-trip the secret through JSON before handing it to the store
if b, err := json.Marshal(secret); err != nil {
return fmt.Errorf("secret %v is not serializable: %v", secret, err)
} else {
var check fi.Secret
if err := json.Unmarshal(b, &check); err != nil {
return fmt.Errorf("secret does not round-trip: %v", err)
}
} Type guard
func validSecret(s *fi.Secret) bool {
if s == nil { return false }
_, err := json.Marshal(s)
return err == nil
} Prevention
- Build secrets with fi.NewSecret(data) rather than hand-assembling structs
- Prefer API-level kops commands over manipulating fi.Secret internals
- Round-trip validate any secret loaded from external sources
- Keep fi.Secret field usage aligned with the kops version in go.mod
When it happens
Trigger: Passing a *fi.Secret with unmarshalable content (e.g. a nil pointer embedded via an unusual construction, or corrupted internal state) into createSecret through GetOrCreateSecret, ReplaceSecret, or MirrorTo.
Common situations: Programmatic use of the fi.SecretStore API (custom controllers/Go code) constructing fi.Secret values manually rather than via fi.NewSecret; secrets loaded from sources that bypass JSON decoding.
Understand the failure class
Background: "JSON serialization failed", "not JSON serializable", "Failed to serialize": why JSON marshaling errors happen and how to fix them — this error's family across 46 libraries.
Related errors
- error serializing secret: %v
- error building annotation patch: %v
- building node patch: %w
- error building node patch: %v
- marshalling nodeupConfig: %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/a58bfd71836e9d9b.
Report an issue: GitHub.