{"record":{"id":"1d594667b4423d6d","repo":"argoproj/argo-workflows","slug":"failed-to-parse-certificate","errorCode":null,"errorMessage":"failed to parse certificate","messagePattern":"failed to parse certificate","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"server/auth/serviceaccount/claims.go","lineNumber":104,"sourceCode":"\t\t}\n\t} else {\n\t\t// Load certificate from file\n\t\tdata, err := os.ReadFile(restConfig.CertFile)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to read certificate file: %w\", err)\n\t\t}\n\t\tblock, _ := pem.Decode(data)\n\t\tif block == nil || block.Type != \"CERTIFICATE\" {\n\t\t\treturn nil, fmt.Errorf(\"failed to parse certificate PEM\")\n\t\t}\n\t\tcert, err = x509.ParseCertificate(block.Bytes)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to parse certificate: %w\", err)\n\t\t}\n\t}\n\n\tif cert == nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse certificate\")\n\t}\n\n\t// Extract username from CommonName (CN)\n\tusername := cert.Subject.CommonName\n\n\t// Extract group information from Organization (O) fields\n\tvar groups []string\n\tfor _, org := range cert.Subject.Organization {\n\t\tif strings.HasPrefix(org, \"system:\") {\n\t\t\tgroups = append(groups, org)\n\t\t}\n\t}\n\n\t// Construct claims object\n\tclaims := &types.Claims{\n\t\tClaims: jwt.Claims{\n\t\t\tSubject: username,\n\t\t\tIssuer:  \"kubernetes/cert\",","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/server/auth/serviceaccount/claims.go#L86-L122","documentation":"Defensive final check in ClaimSetWithX509: after both branches (CertData and CertFile), if the cert variable is still nil this generic error is returned. It should be unreachable in practice because each branch already returns earlier on PEM/parse failures; it acts as a safety net for future code changes that add new branches without setting cert.","triggerScenarios":"Theoretically unreachable with current code: it would require both branches to complete without assigning cert. Hits maintainers who modify ClaimSetWithX509 and add a code path that leaves cert nil, or when the function is refactored.","commonSituations":"Developers extending the function (e.g. adding a new certificate source) forget to assign cert in their branch; users will effectively never see this directly — they'd see the earlier, more specific PEM/parse errors instead.","solutions":["If you see it after a code change, audit every branch of ClaimSetWithX509 and ensure each assigns `cert` or returns an error","Add a unit test covering all certificate-source branches (CertData, CertFile) so nil-cert paths fail in CI","Treat any occurrence as an internal bug; file it with the argo-workflows version and the rest.Config source"],"exampleFix":"// before (new branch leaves cert unset)\nif someNewSource {\n    // parsed but forgot: cert = parsedCert\n}\n// after\nif someNewSource {\n    cert = parsedCert\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"claims, err := ClaimSetWithX509(restConfig)\nif err != nil && err.Error() == \"failed to parse certificate\" {\n    // internal invariant broken; report a bug with the argo-workflows version\n}","preventionTips":["This is a defensive internal check — treat occurrence as an argo-workflows bug and file an issue","If you modified claims.go, ensure every branch assigns `cert` or returns","Add branch-coverage unit tests for ClaimSetWithX509"],"tags":["x509","defensive-check","internal-bug","authentication"],"backgroundTag":"nil-certificate-state","analyzedSha":"35bff19146f5a6ada77468c431f2624bd577e373","analyzedAt":"2026-09-03T19:34:35.908Z","contentChangedAt":"2026-09-03T19:34:35.908Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}