siyuan-note/siyuan · error
OIDC redirect URL is required
Error message
OIDC redirect URL is required
What it means
Provider.New validates the OAuth2/OIDC construction inputs and refuses to build a Provider when the redirect URL argument is empty. The redirect URL is mandatory because every provider (Google, Microsoft, GitHub, custom) embeds it into the oauth2.Config used for the authorization-code flow; without it the AuthCodeURL and token exchange cannot work. This is a fail-fast guard rather than a runtime failure.
Solutions
- Set the redirect/callback URL in the OIDC configuration before calling New (must match the URI registered with the identity provider).
- If the redirect URL is derived from request state, ensure the reverse proxy forwards Host / X-Forwarded-* headers and the code reads them before validation.
- Validate the field at configuration-save time so an empty value can never reach New.
- Update the saved conf via the settings API and retry the sign-in flow.
Example fix
// before
provider, err := New(cfg, cfg.RedirectURL) // cfg.RedirectURL is ""
// after
if cfg.RedirectURL == "" {
cfg.RedirectURL = "https://example.com/api/oidc/callback"
}
provider, err := New(cfg, cfg.RedirectURL) Defensive patterns
Strategy: validation
Validate before calling
if strings.TrimSpace(redirectURL) == "" {
return errors.New("redirect URL must be configured before starting OIDC sign-in")
} Try / catch
if err != nil {
if strings.Contains(err.Error(), "redirect URL is required") {
// surface a configuration error to the admin UI
}
return err
} Prevention
- Make the callback/redirect URL a required field in the settings form with validation on save
- Derive the redirect URL from explicit config, not from request-time headers that can be empty
- Add a pre-flight config check on boot that logs all missing OIDC fields
When it happens
Trigger: Calling New(config, redirectURL) with redirectURL == "" — e.g. building the callback URL from a config field (conf.OIDC / model conf endpoint) that was never filled in, or from a request/HTTP host value that was empty at boot time.
Common situations: Self-hosted instances where the admin never set the external/callback URL; deployments behind a reverse proxy where the forwarded-host header is missing so the code computes an empty redirect URL; fresh configs saved before the callback field was populated; tests constructing a Provider with only a config struct.
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
- GitHub OAuth client secret is required
- OIDC issuer 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/e7c7a25fea3290c6.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/oidc_provider/provider.go:43
const (
googleIssuer = "https://accounts.google.com"
)
type Provider struct {
kind string
oauth2Config *oauth2.Config
verifier *oidc.IDTokenVerifier
}
func New(ctx context.Context, config *conf.OIDC, redirectURL string) (*Provider, error) {
if config == nil {
return nil, errors.New("OIDC configuration is missing")
}
if config.ClientID == "" {
return nil, errors.New("OIDC client ID is required")
}
if redirectURL == "" {
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")View on GitHub (pinned to 9f775e8a12)