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

  1. Construct secrets with fi.NewSecret(data) instead of building the struct literally
  2. Inspect the wrapped %v marshal cause for the offending field type
  3. Print/validate the fi.Secret payload before calling ReplaceSecret/GetOrCreateSecret
  4. 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

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


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/a58bfd71836e9d9b. Report an issue: GitHub.