siyuan-note/siyuan · error
OIDC issuer URL is required
Error message
OIDC issuer URL is required
What it means
After resolving the issuer URL (explicitly configured, or defaulted for Google/Microsoft), New requires it to be non-empty before attempting OIDC discovery. Only the Custom provider can leave IssuerURL empty in the config, so this error means a custom-provider configuration was saved without the issuer endpoint. Discovery cannot proceed without a base issuer URL.
Solutions
- Set IssuerURL in the OIDC config to the IdP's issuer base URL (e.g. https://accounts.example.com), typically the value in the IdP's .well-known/openid-configuration location minus the well-known suffix.
- Trim or remove whitespace-only values; the code trims but rejects blank strings.
- Validate the issuer URL field as required whenever provider == custom in the settings UI.
- If you meant a hosted provider, switch config.Provider to Google/Microsoft/GitHub which have built-in issuers.
Example fix
// before
cfg := &conf.OIDC{Provider: conf.OIDCProviderCustom, IssuerURL: ""}
provider, err := New(cfg, redirectURL)
// after
cfg := &conf.OIDC{Provider: conf.OIDCProviderCustom, IssuerURL: "https://sso.example.com/realms/main"}
provider, err := New(cfg, redirectURL) Defensive patterns
Strategy: validation
Validate before calling
if cfg.Provider == conf.OIDCProviderCustom && strings.TrimSpace(cfg.IssuerURL) == "" {
return errors.New("issuer URL is required for the custom OIDC provider")
} Try / catch
if err != nil {
if strings.Contains(err.Error(), "issuer URL is required") {
// mark the IssuerURL field as the offending setting
}
return err
} Prevention
- Mark IssuerURL required in the UI whenever provider == custom
- Validate the issuer by fetching .well-known/openid-configuration at config-save time
- Trim user input before persisting so whitespace-only values are rejected early
When it happens
Trigger: Calling New with config.Provider == conf.OIDCProviderCustom and strings.TrimSpace(config.IssuerURL) == "" — i.e. the Custom OIDC provider selected but the issuer URL field left blank.
Common situations: Admin selected "Custom" in the settings dialog but skipped the IssuerURL field; whitespace-only value pasted into the field; config JSON hand-edited and the key dropped; issuer URL cleared during troubleshooting and the config saved anyway.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- OIDC issuer URL is required
- OIDC redirect URL is required
- cannot save incomplete notebook crypto configuration
- Conf.Language(249)
- ErrInvalidMode
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/fcdecd61c814ef8a.
Report an issue: GitHub.
Appendix: 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 9f775e8a12)