{"record":{"id":"73cbc975f293b0ee","repo":"siyuan-note/siyuan","slug":"oidc-redirect-url-must-end-with-api-system-oidc-c","errorCode":null,"errorMessage":"OIDC redirect URL must end with /api/system/oidc/callback","messagePattern":"OIDC redirect URL must end with /api/system/oidc/callback","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/oidc.go","lineNumber":635,"sourceCode":"\nfunc oidcValidationRedirectURL(c *gin.Context, config *conf.OIDC, mobile bool) (string, error) {\n\tif mobile {\n\t\treturn oidcMobileRedirectURL, nil\n\t}\n\tif config.RedirectURL != \"\" {\n\t\treturn validatePublicOIDCRedirectURL(config.RedirectURL)\n\t}\n\treturn effectiveOIDCRedirectURL(c, oidcFlowDesktop)\n}\n\nfunc validatePublicOIDCRedirectURL(redirectURL string) (string, error) {\n\tif redirectURL == \"\" {\n\t\treturn \"\", errors.New(\"A public HTTPS OIDC redirect URL is required for remote access\")\n\t}\n\tparsed, err := url.Parse(redirectURL)\n\tif err != nil || parsed.Scheme == \"\" || parsed.Host == \"\" || parsed.Path != \"/api/system/oidc/callback\" ||\n\t\tparsed.User != nil || parsed.RawQuery != \"\" || parsed.Fragment != \"\" {\n\t\treturn \"\", errors.New(\"OIDC redirect URL must end with /api/system/oidc/callback\")\n\t}\n\tif parsed.Scheme != \"https\" {\n\t\treturn \"\", errors.New(\"Public OIDC redirect URL must use HTTPS\")\n\t}\n\treturn parsed.String(), nil\n}\n\nfunc getOIDCProvider(ctx context.Context, redirectURL string) (*oidc_provider.Provider, error) {\n\tversion := oidcConfigurationVersion(Conf.GetOIDC())\n\tkey := version + \"\\x00\" + redirectURL\n\toidcProviders.Lock()\n\tif oidcProviders.version != version {\n\t\toidcProviders.version = version\n\t\toidcProviders.items = map[string]*oidc_provider.Provider{}\n\t}\n\tif provider := oidcProviders.items[key]; provider != nil {\n\t\toidcProviders.Unlock()\n\t\treturn provider, nil","sourceCodeStart":617,"sourceCodeEnd":653,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/model/oidc.go#L617-L653","documentation":"The configured redirect URL parsed but failed structural validation: it must have a non-empty scheme, a non-empty host, a path exactly equal to /api/system/oidc/callback, and no userinfo, query string, or fragment. The message highlights the path because that is the most common failure, but any of those defects trigger it.","triggerScenarios":"validatePublicOIDCRedirectURL receives a URL such as https://host/oidc/callback, https://host/api/system/oidc/callback/ (trailing slash), host/api/system/oidc/callback (no scheme), or https://host/api/system/oidc/callback?next=/ (query).","commonSituations":"Operator copies a redirect URL from another app; trailing slash; path typo; appending query parameters meant for the IdP rather than SiYuan.","solutions":["Set the URL to exactly https://<host>/api/system/oidc/callback with no trailing slash, query, fragment, or userinfo.","Run OIDC validation from the admin UI to confirm the value is accepted.","Mirror the exact same string in the IdP's allowed redirect URIs."],"exampleFix":"// before\nRedirectURL: \"https://notes.example.com/oidc/callback\"\n// after\nRedirectURL: \"https://notes.example.com/api/system/oidc/callback\"","handlingStrategy":"validation","validationCode":"// Validate redirect-URL structure exactly as the kernel does, before saving config.\nfunc checkRedirectURL(s string) error {\n    u, err := url.Parse(s)\n    if err != nil || u.Scheme == \"\" || u.Host == \"\" ||\n        u.Path != \"/api/system/oidc/callback\" ||\n        u.User != nil || u.RawQuery != \"\" || u.Fragment != \"\" {\n        return errors.New(\"redirect URL must be https://<host>/api/system/oidc/callback with no query/fragment\")\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always use the literal path /api/system/oidc/callback with no trailing slash.","Never append query parameters or fragments to the redirect URL.","Mirror the exact same string in the IdP allowed-redirect-URI list."],"tags":["oidc","configuration","redirect-url","validation"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}