siyuan-note/siyuan · error

Public OIDC redirect URL must use HTTPS

Error message

Public OIDC redirect URL must use HTTPS

What it means

validatePublicOIDCRedirectURL parses the configured OIDC redirect URL and requires that it be an absolute https URL ending exactly with /api/system/oidc/callback, with no userinfo, query, or fragment. This error is thrown when the URL passes the shape check but its scheme is not https. SiYuan enforces HTTPS for publicly configured redirect URLs because the OIDC authorization code would otherwise traverse the network unencrypted.

Solutions

  1. Change the configured OIDC redirect URL to use https:// (e.g. https://your-domain/api/system/oidc/callback) in Settings - OIDC or conf.OIDC.RedirectURL
  2. Set up TLS termination (reverse proxy with a certificate) so the callback endpoint is reachable over HTTPS
  3. If this is purely a local desktop flow, clear the custom RedirectURL so the kernel generates the loopback redirect URL instead

Example fix

// before
Conf.GetOIDC().RedirectURL = "http://siyuan.example.com/api/system/oidc/callback"
// after
Conf.GetOIDC().RedirectURL = "https://siyuan.example.com/api/system/oidc/callback"
Defensive patterns

Strategy: validation

Validate before calling

u, err := url.Parse(redirectURL)
if err != nil || u.Scheme != "https" || u.Path != "/api/system/oidc/callback" || u.RawQuery != "" || u.Fragment != "" || u.User != nil {
    return errors.New("redirect URL must be https and end with /api/system/oidc/callback")
}

Prevention

When it happens

Trigger: Calling ValidateOIDCProviderConfiguration, ValidateOIDCConfigurationChange, or starting/validating an OIDC login while conf.OIDC.RedirectURL is set to an http:// URL (e.g. http://example.com/api/system/oidc/callback).

Common situations: Self-hosted setups behind a reverse proxy that terminates TLS but leave the internal redirect URL on http://; users testing on localhost with plain http; configuration copied from an HTTP-only deployment.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/40d185bb4cb12da1. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/oidc.go:582

		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
		oidcProviders.items = map[string]*oidc_provider.Provider{}
	}
	if provider := oidcProviders.items[key]; provider != nil {
		oidcProviders.Unlock()
		return provider, nil
	}
	oidcProviders.Unlock()
	discoveryContext, cancel := context.WithTimeout(ctx, oidcProviderTimeout)

View on GitHub (pinned to 9f775e8a12)