argoproj/argo-workflows · error
issuer empty
Error message
issuer empty
What it means
newSso validates the SSO configuration loaded from the argo-server ConfigMap before constructing the OIDC service. The very first check requires a non-empty Issuer; if sso.issuer is missing, it returns 'issuer empty'. The issuer URL is the root of the OIDC discovery endpoint, so without it no provider metadata can be fetched and SSO cannot function.
Source
Thrown at server/auth/sso/sso.go:126
func providerFactoryOIDC(ctx context.Context, issuer string) (providerInterface, error) {
return oidc.NewProvider(ctx, issuer)
}
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)View on GitHub (pinned to 35bff19146)
Solutions
- Add `sso.issuer: https://<your-provider>/...` to the argo-server SSO ConfigMap (e.g. https://accounts.google.com, https://your-domain/dex) and restart argo-server
- Verify the ConfigMap name/key matches what argo-server mounts (`argo-server-sso` by default) and the YAML nesting is correct
- Check argo-server logs for the full config dump (HTTPClientConfig etc.) to confirm which sso.* keys were actually loaded
Example fix
# ConfigMap # before data: sso.clientId: ... # after data: sso.issuer: https://accounts.google.com sso.clientId: ...
Defensive patterns
Strategy: validation
Validate before calling
var cfg sso.Config
yaml.Unmarshal(cm.Data, &cfg) // after mapping keys like sso.issuer
if cfg.Issuer == "" {
return errors.New("ConfigMap is missing sso.issuer")
}
resp, err := http.Get(strings.TrimSuffix(cfg.Issuer, "/") + "/.well-known/openid-configuration") Type guard
func issuerConfigured(cfg sso.Config) bool { return cfg.Issuer != "" } Try / catch
svc, err := sso.New(ctx, controller, mode, cm, secretsIf, baseHRef, secure)
if err != nil && strings.Contains(err.Error(), "issuer empty") {
return fmt.Errorf("argo-server SSO ConfigMap lacks sso.issuer: %w", err)
} Prevention
- Always include sso.issuer as the first SSO key when templating the ConfigMap
- Verify the issuer with curl '<issuer>/.well-known/openid-configuration' returns 200
- Don't confuse IssuerAlias (display rewriting) with Issuer (required discovery URL)
- Validate the ConfigMap with a lint/schema check before applying
When it happens
Trigger: The argo-server SSO ConfigMap exists but lacks the `sso.issuer` key (or it is an empty string), and argo-server calls New → newSso during startup; also triggered in unit tests that construct Config without Issuer.
Common situations: Fresh SSO setup where the ConfigMap was created from an incomplete template; issuer key removed or misspelled (e.g. `issuer:` with no value or nested under the wrong YAML level); an IssuerAlias-only setup where the actual issuer was accidentally dropped.
Related errors
- failed to append certificates from PEM string
- clientID empty
- no claim found for key: %v
- failed to load system cert pool: %w
- not implemented
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/983939958e21253a.
Report an issue: GitHub.