siyuan-note/siyuan · error
OIDC issuer URL is required
Error message
OIDC issuer URL is required
What it means
Thrown by oidc_provider.New() when issuerURL is empty after the provider switch resolves. Google hard-codes its issuer, GitHub returns early before this check, but Microsoft and Custom rely on config.IssuerURL being populated. If the admin selected Custom or Microsoft but left the issuer URL blank, discovery cannot proceed.
Source
Thrown at kernel/model/oidc_provider/provider.go:61
return nil, errors.New("OIDC redirect URL is required")
}
if config.Provider == conf.OIDCProviderGitHub && config.ClientSecret == "" {
return nil, errors.New("GitHub OAuth client secret is required")
}
issuerURL := strings.TrimSpace(config.IssuerURL)
switch config.Provider {
case conf.OIDCProviderGoogle:
issuerURL = googleIssuer
case conf.OIDCProviderMicrosoft:
// Microsoft 多租户端点的 issuer 会随租户变化,必须使用租户专属 issuer。
case conf.OIDCProviderCustom:
case conf.OIDCProviderGitHub:
return newGitHub(config, redirectURL), nil
default:
return nil, fmt.Errorf("unsupported OIDC provider [%s]", config.Provider)
}
if issuerURL == "" {
return nil, errors.New("OIDC issuer URL is required")
}
discovered, err := oidc.NewProvider(ctx, issuerURL)
if err != nil {
return nil, fmt.Errorf("discover OIDC provider failed: %w", err)
}
scopes := append([]string{}, config.Scopes...)
if !contains(scopes, oidc.ScopeOpenID) {
scopes = append([]string{oidc.ScopeOpenID}, scopes...)
}
return &Provider{
kind: conf.OIDCProviderCustom,
oauth2Config: &oauth2.Config{
ClientID: config.ClientID,
ClientSecret: config.ClientSecret,
Endpoint: discovered.Endpoint(),
RedirectURL: redirectURL,
Scopes: scopes,
},View on GitHub (pinned to 251596fc0d)
Solutions
- For Custom provider: enter the full issuer URL from your OIDC provider's well-known configuration (e.g., https://provider.example.com/.well-known/openid-configuration — use the base, not the .well-known path).
- For Microsoft: provide the tenant-specific issuer URL since the multi-tenant endpoint issuer varies.
- Validate IssuerURL is non-empty in the API handler when provider is Custom or Microsoft.
Example fix
// before config.Provider = conf.OIDCProviderCustom config.IssuerURL = "" // after config.Provider = conf.OIDCProviderCustom config.IssuerURL = "https://keycloak.example.com/realms/myrealm"
Defensive patterns
Strategy: validation
Validate before calling
if (config.Provider == conf.OIDCProviderCustom || config.Provider == conf.OIDCProviderMicrosoft) && strings.TrimSpace(config.IssuerURL) == "" {
return nil, errors.New("OIDC issuer URL is required for custom and Microsoft providers")
}
provider, err := oidc_provider.New(ctx, config, redirectURL) Type guard
func hasIssuerURL(c *conf.OIDC) bool {
switch c.Provider {
case conf.OIDCProviderGoogle, conf.OIDCProviderGitHub:
return true // issuer is hardcoded or not needed
}
return strings.TrimSpace(c.IssuerURL) != ""
} Prevention
- For Custom/Microsoft providers, always fill in the IssuerURL field.
- Verify the issuer URL by appending /.well-known/openid-configuration and checking it returns JSON.
When it happens
Trigger: Calling New() with config.Provider == conf.OIDCProviderCustom or conf.OIDCProviderMicrosoft, and config.IssuerURL is empty or whitespace-only (TrimSpace yields empty). The switch falls through without setting issuerURL, and the subsequent empty check fires.
Common situations: The admin chose 'Custom' OIDC provider to connect a self-hosted Keycloak/Authelia/etc. but did not fill in the issuer URL (e.g., https://keycloak.example.com/realms/myrealm). The Microsoft provider was selected but the tenant-specific issuer URL was not provided.
Related errors
- OIDC client ID is required
- unsupported OIDC provider [%s]
- OIDC login is not enabled
- OIDC client ID is required
- OIDC issuer URL is required
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/fcdecd61c814ef8a.
Report an issue: GitHub.