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

  1. Set the redirect/callback URL in the OIDC configuration before calling New (must match the URI registered with the identity provider).
  2. 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.
  3. Validate the field at configuration-save time so an empty value can never reach New.
  4. 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

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


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)