siyuan-note/siyuan · error
Desktop OIDC login requires a loopback listener
Error message
Desktop OIDC login requires a loopback listener
What it means
Desktop OIDC login intentionally only supports a loopback redirect: when the flow is desktop (not web/mobile) and the HTTP request originates from a non-local client, effectiveOIDCRedirectURL cannot build a safe redirect and returns this error instead of exposing the kernel to remote redirect manipulation.
Solutions
- Access SiYuan via localhost/127.0.0.1 when initiating desktop OIDC login
- If remote access is intended, use the web flow so the configured public HTTPS RedirectURL is validated instead
- Use the mobile flow, which has its own fixed redirect URL
Example fix
// before
fetch("https://siyuan.example.com/api/system/oidc/start") // desktop flow, remote
// after
fetch("http://127.0.0.1:6806/api/system/oidc/start") // local loopback Defensive patterns
Strategy: validation
Validate before calling
const isLocal = ['127.0.0.1', 'localhost', '::1'].includes(location.hostname);
if (!isLocal) console.warn('desktop OIDC start must be initiated from loopback'); Try / catch
redirectURL, err := effectiveOIDCRedirectURL(c, oidcFlowDesktop)
if err != nil {
http.Error(w, "start OIDC login from http://127.0.0.1 or use the web/mobile flow", 400)
} Prevention
- Initiate desktop OIDC login from localhost only
- Use the web flow with a public HTTPS redirect URL for remote access
- Avoid reverse proxies on the desktop login path
When it happens
Trigger: effectiveOIDCRedirectURL with flow == oidcFlowDesktop, IsLocalRequest(c) == false, and the request is neither the web flow nor using the mobile redirect URL; called from OIDCStart or oidcValidationRedirectURL.
Common situations: Starting desktop OIDC login from a browser on another machine pointed at the kernel's LAN/public address; reverse-proxy setup forwarding remote traffic without switching to the web flow or configuring a public redirect URL.
Understand the failure class
Background: "You do not have permission" / 403 Forbidden errors: authenticated but not allowed — causes and fixes across open-source libraries — this error's family across 31 libraries.
Related errors
- A loopback OIDC redirect URL is required for local access
- A public HTTPS OIDC redirect URL is required for remote…
- discover OIDC provider failed
- exchange OIDC authorization code failed
- OIDC redirect URL must end with /api/system/oidc/callback
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/910f209801dde44f.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/oidc.go:549
return nil
}
if requireRemoteRedirect {
if _, err := validatePublicOIDCRedirectURL(config.RedirectURL); err != nil {
return err
}
}
return ValidateOIDCProviderConfiguration(ctx, config)
}
func effectiveOIDCRedirectURL(c *gin.Context, flow string) (string, error) {
if flow == oidcFlowMobile {
return oidcMobileRedirectURL, nil
}
if flow == oidcFlowWeb && !IsLocalRequest(c) {
return validatePublicOIDCRedirectURL(Conf.GetOIDC().RedirectURL)
}
if !IsLocalRequest(c) {
return "", errors.New("Desktop OIDC login requires a loopback listener")
}
scheme := "http"
if c.Request.TLS != nil || c.GetHeader("X-Forwarded-Proto") == "https" {
scheme = "https"
}
host := c.Request.Host
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)View on GitHub (pinned to 9f775e8a12)