{"record":{"id":"5b542fca5d7e2227","repo":"argoproj/argo-workflows","slug":"failed-to-parse-private-key-if-you-have-already-d","errorCode":null,"errorMessage":"failed to parse private key. If you have already defined a Secret named %s, delete it and retry: %w","messagePattern":"failed to parse private key\\. If you have already defined a Secret named (.+?), delete it and retry: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/auth/sso/sso.go","lineNumber":206,"sourceCode":"\t_, err = secretsIf.Create(ctx, &apiv1.Secret{\n\t\tObjectMeta: metav1.ObjectMeta{Name: secretName},\n\t\tData:       map[string][]byte{cookieEncryptionPrivateKeySecretKey: x509.MarshalPKCS1PrivateKey(generatedKey)},\n\t}, metav1.CreateOptions{})\n\tisSecretAlreadyExists := false\n\tif err != nil {\n\t\tisSecretAlreadyExists = apierr.IsAlreadyExists(err)\n\t\tif !isSecretAlreadyExists {\n\t\t\treturn nil, fmt.Errorf(\"failed to create secret: %w\", err)\n\t\t}\n\t}\n\tsecret, err := secretsIf.Get(ctx, secretName, metav1.GetOptions{})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to read secret: %w\", err)\n\t}\n\tprivateKey, err := x509.ParsePKCS1PrivateKey(secret.Data[cookieEncryptionPrivateKeySecretKey])\n\tif err != nil {\n\t\tif isSecretAlreadyExists {\n\t\t\treturn nil, fmt.Errorf(\"failed to parse private key. If you have already defined a Secret named %s, delete it and retry: %w\", secretName, err)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"failed to parse private key: %w\", err)\n\t}\n\n\tclientID := clientIDObj.Data[c.ClientID.Key]\n\tif clientID == nil {\n\t\treturn nil, fmt.Errorf(\"key %s missing in secret %s\", c.ClientID.Key, c.ClientID.Name)\n\t}\n\tclientSecret := clientSecretObj.Data[c.ClientSecret.Key]\n\tif clientSecret == nil {\n\t\treturn nil, fmt.Errorf(\"key %s missing in secret %s\", c.ClientSecret.Key, c.ClientSecret.Name)\n\t}\n\tconfig := &oauth2.Config{\n\t\tClientID:     string(clientID),\n\t\tClientSecret: string(clientSecret),\n\t\tRedirectURL:  c.RedirectURL,\n\t\tEndpoint:     provider.Endpoint(),\n\t\tScopes:       append(c.Scopes, oidc.ScopeOpenID),","sourceCodeStart":188,"sourceCodeEnd":224,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/server/auth/sso/sso.go#L188-L224","documentation":"When the private key stored in the argo-sso secret cannot be parsed with x509.ParsePKCS1PrivateKey AND the code path just saw AlreadyExists on create (meaning the secret predates this pod and was created by the operator, not argo), newSso returns this message to tell you the pre-existing secret's contents are not a valid PKCS#1 RSA key and the secret must be deleted so argo can recreate it.","triggerScenarios":"Calling New() where a Secret named 'argo-sso' already exists with a cookieEncryptionPrivateKeySecretKey ('cookie-secret-key') value that is not a marshalled PKCS#1 RSA key, and Create returned AlreadyExists.","commonSituations":"User manually created an 'argo-sso' secret (e.g. holding OIDC client credentials) — name collides with the cookie secret; the key was replaced/corrupted by a script or was generated by a different argo version/path.","solutions":["Delete the conflicting secret: kubectl -n argo delete secret argo-sso, then restart argo-server","Check the secret's data under 'cookie-secret-key' is a PKCS#1 DER blob (not PEM, not client credentials)","Move your own OIDC credentials to a differently named secret and point sso.clientId/clientSecret at it"],"exampleFix":"# before\nkubectl create secret generic argo-sso --from-file=client-id=... # collides with cookie secret\n# after\nkubectl delete secret argo-sso -n argo\nkubectl create secret generic argo-sso-creds --from-literal=client-id=... # use this name in sso config","handlingStrategy":"validation","validationCode":"secret, _ := secretsIf.Get(ctx, \"argo-sso\", metav1.GetOptions{})\nif secret != nil {\n    if _, err := x509.ParsePKCS1PrivateKey(secret.Data[\"cookie-secret-key\"]); err != nil {\n        return fmt.Errorf(\"argo-sso secret holds an invalid cookie key; delete it: %w\", err)\n    }\n}","typeGuard":null,"tryCatchPattern":"if _, err := sso.New(ctx, cfg, secretsIf, baseHRef, secure); err != nil {\n    if strings.Contains(err.Error(), \"delete it and retry\") {\n        _ = secretsIf.Delete(ctx, \"argo-sso\", metav1.DeleteOptions{})\n        // restart argo-server so a fresh key is generated\n    }\n    return err\n}","preventionTips":["Never name your own OIDC credentials secret 'argo-sso' — it is reserved for the cookie key","Only restore argo-sso from backups taken by argo itself","Keep client credentials in a separate secret referenced by sso.clientId/clientSecret"],"tags":["x509","secrets","sso","kubernetes"],"backgroundTag":"invalid-private-key-secret","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"}