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 failView on GitHub (pinned to 35bff19146)
Solutions
- Add sso.clientSecret.name and sso.clientSecret.key to the workflow-controller-configmap, pointing at the secret holding the OIDC client secret
- Check the rendered configmap (kubectl get cm workflow-controller-configmap -o yaml) for an empty or misspelled clientSecret block
- 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
- Use the SSO configmap example as a template so all name/key pairs are present
- Lint configmaps with a schema check for issuer/clientId/clientSecret blocks
- Render Helm/Kustomize output and assert no empty sso fields before deploy
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
- key %s missing in secret %s
- memoization configmap doesn't have %s label, refusing to use
- protocol %s is not allowed
- executor plugin metadata name is mandatory
- failed to list SSO RBAC service accounts: %w
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/208bff7ed38b7cb0.
Report an issue: GitHub.