argoproj/argo-workflows · error

failed to parse private key. If you have already defined a S

Error message

failed to parse private key. If you have already defined a Secret named %s, delete it and retry: %w

What it means

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.

Source

Thrown at server/auth/sso/sso.go:206

	_, err = secretsIf.Create(ctx, &apiv1.Secret{
		ObjectMeta: metav1.ObjectMeta{Name: secretName},
		Data:       map[string][]byte{cookieEncryptionPrivateKeySecretKey: x509.MarshalPKCS1PrivateKey(generatedKey)},
	}, metav1.CreateOptions{})
	isSecretAlreadyExists := false
	if err != nil {
		isSecretAlreadyExists = apierr.IsAlreadyExists(err)
		if !isSecretAlreadyExists {
			return nil, fmt.Errorf("failed to create secret: %w", err)
		}
	}
	secret, err := secretsIf.Get(ctx, secretName, metav1.GetOptions{})
	if err != nil {
		return nil, fmt.Errorf("failed to read secret: %w", err)
	}
	privateKey, err := x509.ParsePKCS1PrivateKey(secret.Data[cookieEncryptionPrivateKeySecretKey])
	if err != nil {
		if isSecretAlreadyExists {
			return nil, fmt.Errorf("failed to parse private key. If you have already defined a Secret named %s, delete it and retry: %w", secretName, err)
		}
		return nil, fmt.Errorf("failed to parse private key: %w", err)
	}

	clientID := clientIDObj.Data[c.ClientID.Key]
	if clientID == nil {
		return nil, fmt.Errorf("key %s missing in secret %s", c.ClientID.Key, c.ClientID.Name)
	}
	clientSecret := clientSecretObj.Data[c.ClientSecret.Key]
	if clientSecret == nil {
		return nil, fmt.Errorf("key %s missing in secret %s", c.ClientSecret.Key, c.ClientSecret.Name)
	}
	config := &oauth2.Config{
		ClientID:     string(clientID),
		ClientSecret: string(clientSecret),
		RedirectURL:  c.RedirectURL,
		Endpoint:     provider.Endpoint(),
		Scopes:       append(c.Scopes, oidc.ScopeOpenID),

View on GitHub (pinned to 35bff19146)

Solutions

  1. Delete the conflicting secret: kubectl -n argo delete secret argo-sso, then restart argo-server
  2. Check the secret's data under 'cookie-secret-key' is a PKCS#1 DER blob (not PEM, not client credentials)
  3. Move your own OIDC credentials to a differently named secret and point sso.clientId/clientSecret at it

Example fix

# before
kubectl create secret generic argo-sso --from-file=client-id=... # collides with cookie secret
# after
kubectl delete secret argo-sso -n argo
kubectl create secret generic argo-sso-creds --from-literal=client-id=... # use this name in sso config
Defensive patterns

Strategy: validation

Validate before calling

secret, _ := secretsIf.Get(ctx, "argo-sso", metav1.GetOptions{})
if secret != nil {
    if _, err := x509.ParsePKCS1PrivateKey(secret.Data["cookie-secret-key"]); err != nil {
        return fmt.Errorf("argo-sso secret holds an invalid cookie key; delete it: %w", err)
    }
}

Try / catch

if _, err := sso.New(ctx, cfg, secretsIf, baseHRef, secure); err != nil {
    if strings.Contains(err.Error(), "delete it and retry") {
        _ = secretsIf.Delete(ctx, "argo-sso", metav1.DeleteOptions{})
        // restart argo-server so a fresh key is generated
    }
    return err
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Related errors


AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03). Data as JSON: /api/errors/5b542fca5d7e2227. Report an issue: GitHub.