siyuan-note/siyuan · error
A loopback OIDC redirect URL is required for local access
Error message
A loopback OIDC redirect URL is required for local access
What it means
Returned by effectiveOIDCRedirectURL (kernel/model/oidc.go:613) for the desktop flow when the request IS local (IsLocalRequest passed earlier) but c.Request.Host, after parsing via util.IsLocalHost, is not a loopback host. This catches proxied or Host-header-rewritten requests that look local to the connection but carry a non-loopback Host.
Source
Thrown at kernel/model/oidc.go:613
}
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)
}
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")
}View on GitHub (pinned to 251596fc0d)
Solutions
- Access SiYuan directly via 127.0.0.1:6806 or localhost:6806 for the desktop OIDC flow so Host is loopback.
- Configure the proxy to pass Host as 127.0.0.1:6806 for desktop login, or use the web flow with a public redirect URL.
- Avoid /etc/hosts tricks with non-localhost names for desktop OIDC.
Example fix
# before — proxy sets external Host proxy_set_header Host siyuan.corp; # after — for local desktop flow, access directly open http://127.0.0.1:6806 # Host: 127.0.0.1:6806 -> ok
Defensive patterns
Strategy: validation
Validate before calling
if !util.IsLocalHost(c.Request.Host) {
return errors.New("request Host is not loopback; use 127.0.0.1")
} Type guard
func hostIsLoopback(host string) bool { return util.IsLocalHost(host) } Prevention
- For desktop OIDC, browse to SiYuan by 127.0.0.1, not a mapped hostname.
- Reverse proxies should preserve a loopback Host for local flows, or route remote users to the web flow.
When it happens
Trigger: A reverse proxy on the same machine forwards to SiYuan with a non-loopback Host header; a browser uses a custom Host mapping (e.g. via /etc/hosts to a non-localhost name) that still routes to 127.0.0.1.
Common situations: Local reverse proxy (Caddy/Nginx) in front of SiYuan preserving an external hostname; debugging with a custom domain that resolves to loopback.
Related errors
- Desktop OIDC login requires a loopback listener
- OIDC issuer URL must use HTTPS unless it is a loopback addre
- missing query param [u]
- decode [u] failed: %s
- parse [u] failed: %s
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/b8a839c852f17ca9.
Report an issue: GitHub.