{"record":{"id":"077c8a62b2fa74ca","repo":"kubernetes/kops","slug":"error-parsing-subject-v","errorCode":null,"errorMessage":"error parsing Subject: %v","messagePattern":"error parsing Subject: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/fitasks/keypair.go","lineNumber":203,"sourceCode":"\t\t} else if changes.Issuer != \"\" {\n\t\t\tcreateCertificate = true\n\t\t\tklog.V(8).Infof(\"creating certificate new Issuer\")\n\t\t} else if changes.Type != \"\" {\n\t\t\tcreateCertificate = true\n\t\t\tklog.Infof(\"creating certificate %q as Type has changed (actual=%v, expected=%v)\", name, a.Type, e.Type)\n\t\t} else if a.LegacyFormat {\n\t\t\tchangeStoredFormat = true\n\t\t} else {\n\t\t\tklog.Warningf(\"Ignoring changes in key: %v\", fi.DebugAsJsonString(changes))\n\t\t}\n\t}\n\n\tif createCertificate {\n\t\tklog.V(2).Infof(\"Creating PKI keypair %q\", name)\n\n\t\tsubjectPkix, err := parsePkixName(e.Subject)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error parsing Subject: %v\", err)\n\t\t}\n\n\t\tif len(subjectPkix.ToRDNSequence()) == 0 {\n\t\t\treturn fmt.Errorf(\"subject name was empty for SSL keypair %q\", *e.Name)\n\t\t}\n\n\t\tsigner := fi.CertificateIDCA\n\t\tif e.Signer != nil {\n\t\t\tsigner = fi.ValueOf(e.Signer.Name)\n\t\t}\n\n\t\treq := pki.IssueCertRequest{\n\t\t\tSigner:         signer,\n\t\t\tType:           e.Type,\n\t\t\tSubject:        *subjectPkix,\n\t\t\tAlternateNames: e.AlternateNames,\n\t\t}\n","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/fitasks/keypair.go#L185-L221","documentation":"When Render decides a new certificate must be created, it parses the task's Subject string (comma-separated k=v tokens) via parsePkixName, which only accepts keys 'cn' and 'o' and requires every token to be k=v. Any malformed subject produces 'error parsing Subject'. This is a strict local parser, not the full OpenSSL DN syntax.","triggerScenarios":"Render with createCertificate=true and e.Subject that parsePkixName rejects: tokens without '=' (e.g. 'example.com'), unknown keys (e.g. 'OU=foo', 'L=city', 'C=US'), or empty subject string.","commonSituations":"User sets cluster spec values (e.g. kubelet, master DNS keypair subjects) using full LDAP-style DNs with unsupported RDNs; subject accidentally left empty; whitespace/unquoted commas producing bare tokens.","solutions":["Rewrite the Subject using only CN= and O= tokens, e.g. 'CN=apiserver,O=kops'","Remove unsupported RDN fields (OU, L, ST, C are not accepted by this parser)","Ensure the subject is non-empty and each comma-separated token contains '='","Check the task/spec source (e.g. cluster spec field feeding e.Subject) for typos"],"exampleFix":"// before\nSubject: \"CN=ca,OU=Systems,L=SF\"\n// after\nSubject: \"CN=ca,O=Systems\"","handlingStrategy":"validation","validationCode":"func validSubject(s string) bool { for _, tok := range strings.Split(s, \",\") { kv := strings.SplitN(strings.TrimSpace(tok), \"=\", 2); if len(kv) != 2 { return false }; switch strings.ToLower(kv[0]) { case \"cn\", \"o\": default: return false } }; return s != \"\" }","typeGuard":null,"tryCatchPattern":"if err != nil { if strings.Contains(err.Error(), \"error parsing Subject\") { // surface allowed keys (cn,o) to the operator } return err }","preventionTips":["Restrict subjects to comma-separated CN= and O= tokens only","Validate spec-provided subjects before running kops update","Do not copy OpenSSL-style DNs (OU/L/C) into kops subject fields"],"tags":["pki","validation","subject-parse","x509"],"backgroundTag":"invalid-certificate-subject","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}