siyuan-note/siyuan · error

A public HTTPS OIDC redirect URL is required for remote acce

Error message

A public HTTPS OIDC redirect URL is required for remote access

What it means

Thrown by validatePublicOIDCRedirectURL when the redirect URL is empty but a public redirect URL is required. The kernel refuses to derive a loopback URL for remote (non-loopback / Docker) access because the IdP must redirect to a stable, publicly-reachable HTTPS endpoint configured by the operator.

Source

Thrown at kernel/model/oidc.go:630

	if !util.IsLocalHost(host) {
		return "", errors.New("A loopback OIDC redirect URL is required for local access")
	}
	return scheme + "://" + host + "/api/system/oidc/callback", nil
}

func oidcValidationRedirectURL(c *gin.Context, config *conf.OIDC, mobile bool) (string, error) {
	if mobile {
		return oidcMobileRedirectURL, nil
	}
	if config.RedirectURL != "" {
		return validatePublicOIDCRedirectURL(config.RedirectURL)
	}
	return effectiveOIDCRedirectURL(c, oidcFlowDesktop)
}

func validatePublicOIDCRedirectURL(redirectURL string) (string, error) {
	if redirectURL == "" {
		return "", errors.New("A public HTTPS OIDC redirect URL is required for remote access")
	}
	parsed, err := url.Parse(redirectURL)
	if err != nil || parsed.Scheme == "" || parsed.Host == "" || parsed.Path != "/api/system/oidc/callback" ||
		parsed.User != nil || parsed.RawQuery != "" || parsed.Fragment != "" {
		return "", errors.New("OIDC redirect URL must end with /api/system/oidc/callback")
	}
	if parsed.Scheme != "https" {
		return "", errors.New("Public OIDC redirect URL must use HTTPS")
	}
	return parsed.String(), nil
}

func getOIDCProvider(ctx context.Context, redirectURL string) (*oidc_provider.Provider, error) {
	version := oidcConfigurationVersion(Conf.GetOIDC())
	key := version + "\x00" + redirectURL
	oidcProviders.Lock()
	if oidcProviders.version != version {
		oidcProviders.version = version

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Set Conf.OIDC.RedirectURL to a public HTTPS URL of the form https://<host>/api/system/oidc/callback in Settings - About - OIDC.
  2. Register that exact URL in the IdP's allowed redirect URIs.
  3. If you only need local access, reach SiYuan via 127.0.0.1/localhost so the loopback-derived URL is used instead.

Example fix

// before
RedirectURL: ""
// after
RedirectURL: "https://notes.example.com/api/system/oidc/callback"
Defensive patterns

Strategy: validation

Validate before calling

// Before allowing a remote web-flow start, ensure a public HTTPS redirect URL is configured.
func ensurePublicRedirectURL(remote bool) error {
    if !remote {
        return nil // loopback access derives its own URL
    }
    if Conf.OIDC.RedirectURL == "" {
        return errors.New("set a public HTTPS OIDC RedirectURL before exposing SiYuan remotely")
    }
    return nil
}

Prevention

When it happens

Trigger: POST /api/system/oidc/start with flow=web from a non-local client while Conf.OIDC.RedirectURL is unset (effectiveOIDCRedirectURL -> validatePublicOIDCRedirectURL at oidc.go:602); or the validate flow reaching oidcValidationRedirectURL with a candidate config whose RedirectURL is empty.

Common situations: Deploying SiYuan behind a reverse proxy or in Docker and enabling OIDC without filling the public redirect URL field; migrating from loopback-only to remote access without updating config.

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/27c73f8988f12c25. Report an issue: GitHub.