argoproj/argo-workflows · error

clientID empty

Error message

clientID empty

What it means

newSso requires both the Kubernetes Secret name and the key inside it for the OIDC client ID (sso.clientID.name and sso.clientID.key). If either is empty the constructor returns 'clientID empty'. The client ID identifies the argo-server application to the OIDC provider and is stored in a Secret rather than the ConfigMap for consistency with clientSecret handling.

Source

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

func New(ctx context.Context, c Config, secretsIf corev1.SecretInterface, baseHRef string, secure bool) (Interface, error) {
	return newSso(ctx, providerFactoryOIDC, c, secretsIf, baseHRef, secure)
}

func newSso(
	ctx context.Context,
	factory providerFactory,
	c Config,
	secretsIf corev1.SecretInterface,
	baseHRef string,
	secure bool,
) (Interface, error) {
	baseHRef = authcookie.NormalizePath(baseHRef)
	if c.Issuer == "" {
		return nil, fmt.Errorf("issuer empty")
	}
	if c.ClientID.Name == "" || c.ClientID.Key == "" {
		return nil, fmt.Errorf("clientID empty")
	}
	if c.ClientSecret.Name == "" || c.ClientSecret.Key == "" {
		return nil, fmt.Errorf("clientSecret empty")
	}
	clientSecretObj, err := secretsIf.Get(ctx, c.ClientSecret.Name, metav1.GetOptions{})
	if err != nil {
		return nil, err
	}

	// Create http client
	httpClientConfig := HTTPClientConfig{
		InsecureSkipVerify: c.InsecureSkipVerify,
		RootCA:             c.RootCA,
	}
	httpClient, err := createHTTPClient(httpClientConfig)
	if err != nil {
		return nil, fmt.Errorf("failed to create HTTP client: %w", err)
	}

View on GitHub (pinned to 35bff19146)

Solutions

  1. Create/extend the SSO Secret (default name `argo-server-sso-secret`) with a key holding the client ID, e.g. `kubectl create secret generic argo-server-sso-secret --from-literal=client-id=YOUR_CLIENT_ID`
  2. Set `sso.clientID.name: argo-server-sso-secret` and `sso.clientID.key: client-id` in the argo-server SSO ConfigMap and restart argo-server
  3. Ensure the Secret exists in the argo namespace and is readable by the argo-server service account

Example fix

# ConfigMap
# before
sso.clientSecret:
  name: argo-server-sso-secret
  key: client-secret
# after
sso.clientID:
  name: argo-server-sso-secret
  key: client-id
sso.clientSecret:
  name: argo-server-sso-secret
  key: client-secret
Defensive patterns

Strategy: validation

Validate before calling

sec, err := clientset.CoreV1().Secrets(ns).Get(ctx, "argo-server-sso-secret", metav1.GetOptions{})
if err != nil { return err }
if _, ok := sec.Data["client-id"]; !ok {
    return errors.New("Secret argo-server-sso-secret lacks key client-id")
}
// and ensure ConfigMap has sso.clientID.name/key set

Type guard

func clientIDConfigured(cfg sso.Config) bool {
    return cfg.ClientID.Name != "" && cfg.ClientID.Key != ""
}

Try / catch

svc, err := sso.New(ctx, controller, mode, cm, secretsIf, baseHRef, secure)
if err != nil && strings.Contains(err.Error(), "clientID empty") {
    return fmt.Errorf("set sso.clientID.name/key in the SSO ConfigMap and provide the Secret: %w", err)
}

Prevention

When it happens

Trigger: argo-server SSO ConfigMap sets sso.issuer and sso.clientSecret but the `sso.clientID.name` / `sso.clientID.key` keys are absent or blank, so newSso's validation fails during argo-server startup (or when tests build Config with an empty ClientID).

Common situations: Older SSO configurations that specified the client ID only in the ConfigMap (pre-3.x style) not migrated to the Secret-based format; typo in the ConfigMap keys; partial ConfigMap template where the clientID section was deleted.

Related errors


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