argoproj/argo-workflows · error

clientSecret empty

Error message

clientSecret empty

What it means

newSso validates the SSO Config before doing any kubernetes calls: both the Secret name and the data key for the OAuth client secret must be set (c.ClientSecret.Name and c.ClientSecret.Key). If either is empty, the OIDC client cannot be built, so construction fails immediately with 'clientSecret empty'. This is a static config check, not a kubernetes error.

Source

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

}

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)
	}

	oidcContext := oidc.ClientContext(ctx, httpClient)
	// Some offspec providers like Azure, Oracle IDCS have oidc discovery url different from issuer url which causes issuerValidation to fail

View on GitHub (pinned to 35bff19146)

Solutions

  1. Add sso.clientSecret.name and sso.clientSecret.key to the workflow-controller-configmap, pointing at the secret holding the OIDC client secret
  2. Check the rendered configmap (kubectl get cm workflow-controller-configmap -o yaml) for an empty or misspelled clientSecret block
  3. Restart the argo-server pod after fixing the config so New() re-runs

Example fix

# before
sso: {
  issuer: https://accounts.google.com
  clientId: {name: argo-sso, key: client-id}
}
# after
sso: {
  issuer: https://accounts.google.com
  clientId: {name: argo-sso, key: client-id}
  clientSecret: {name: argo-sso, key: client-secret}
}
Defensive patterns

Strategy: validation

Validate before calling

cfg := ssoConfig
if cfg.ClientSecret.Name == "" || cfg.ClientSecret.Key == "" {
    return fmt.Errorf("sso.clientSecret.name and sso.clientSecret.key must both be set")
}

Try / catch

if _, err := sso.New(ctx, cfg, secretsIf, baseHRef, secure); err != nil {
    if strings.Contains(err.Error(), "clientSecret empty") {
        return fmt.Errorf("SSO misconfigured: set sso.clientSecret.{name,key} in workflow-controller-configmap: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling New (server startup with SSO enabled) when the workflow-controller-configmap's sso.clientSecret.name or sso.clientSecret.key is omitted or set to an empty string.

Common situations: Partially filled SSO config in the configmap (issuer and clientID filled in but clientSecret block forgotten); a typo'd YAML key such as 'clientSecretKey' instead of the nested name/key structure; rendering Helm values that drop empty fields.

Related errors


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